1. 程式人生 > >C語言學習筆記(七)---一些刷題記錄

C語言學習筆記(七)---一些刷題記錄

最近在學校的oj上做了一些題目,都不是很難,今天本想統一寫一下題解但時間太晚,篇幅太長,於是先寫三道比較基礎的。這兩天被一道題卡了好久,最後在dalao的指導下改了輸入方式就過了。我們討論了好久也沒弄清楚到底是哪出了問題,有點難過,想早點休息。
學校的oj外網最近好像一直上不了,於是就先不貼連結了。
286是一道關於字串處理的分支結構練習題(一道閱讀題)。
517是一道關於陣列的分支和迴圈結構練習題。
288是一道典型素數判斷題,相關的演算法很有意思,我打算單獨寫一篇文章來簡單介紹一下這些演算法。

286. 密碼註冊規則

時間限制 1000 ms 記憶體限制 65536 KB
題目描述


為保護交易安全,某寶在會員註冊時,對密碼有嚴格的要求。 密碼必須符合以下特徵: 1.密碼的長度大於等於8。 2.密碼中的字元應該來自下面4組“字元類別”中的至少3組: ①大寫字母:ABCD…XYZ ②小寫字母:abcd…xyz ③數字:1234567890 ④特殊符號:[email protected]#$%^&*()-=。 請判別輸入的密碼是否符合規則。

輸入格式
每行的輸入資料是一串密碼,密碼長度 不會超過50,且不會包含以上 4 種之外的字元類別。 若輸入“END”則結束程式

輸出格式
符合規則的輸出”YES”,否則輸出“NO”

輸入樣例
123456
20130410BUPT
20130410Bupt

[email protected]
END

輸出樣例
NO
NO
YES
YES

//  286. 密碼註冊規則
//
//  Created by passer_by_a on 10/25/17.
//  Copyright © 2017 passer_by_a. All rights reserved.
//

#include <stdio.h>
int main() {
    char a[52]={0};
    int i,t;
    while(1)
    {
        t=0;
        int c[5]={0};//
        for(i=1;;i++)
        {
            scanf
("%c",&a[i]); if(a[i]=='\n') break; if(a[i]>='a'&&a[i]<='z') c[1]=1; else if(a[i]>='0'&&a[i]<='9') c[2]=1; else if(a[i]>='A'&&a[i]<='Z') c[3]=1; else c[4]=1; } if(a[1]=='E'&&a[2]=='N'&&a[3]=='D') break; for(int j=1;j<=4;j++) { t+=c[j]; } if(t<=2||i<=7) printf("NO\n");//判斷是否合法 else printf("YES\n"); } return 0; }

執行時間: 2 ms 使用記憶體: 11024 KB
這道題其實很簡單,我的思路是一個一個接收字元並判斷屬於哪種字元,並記錄某種字元是否出現過。一開始我沒看清楚題意,還特意定義了一個字元陣列來存放那些特殊字元,一個一個比對,很麻煩。但其實題意裡有寫只有這四種字元所以只要不是那三種就可以了。

517. 今年的第幾天

題目描述
輸入年、月、日,計算該天是本年的第幾天。
友情提示,平年和閏年的區別:
公元年數可被4整除為閏年,但是正百的年數必須是可以被400整除的才是閏年.其他都是平年.閏年的2月有29天,而平年二月有28天.例如:1996年是閏年,2000年是閏年,1900年是平年,1997年是平年.

輸入格式
包括三個整數年(1<=Y<=3000)、月(1<=M<=12)、日(1<=D<=31)。

輸出格式
輸出一個整數,代表Input中的年、月、日對應本年的第幾天。

輸入樣例
1990 9 20
輸出樣例
263

//  517. 今年的第幾天
//
//  Created by passer_by_a on 10/19/17.
//  Copyright © 2017 passer_by_a. All rights reserved.
//
#include<stdio.h>
int mon[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int monr[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int main(){
    int n,x,y,z;
    int i,j;
    int ans;
        ans=0;
        scanf("%d %d %d",&x,&y,&z);
        if((x%4==0&&x%100!=0)||x%400==0)//判斷閏年
            for(j=1;j<y;j++){
                ans+=monr[j];
            }
        else for(j=1;j<y;j++){
            ans+=mon[j];
        }
        ans+=z;
        printf("%d",ans);
    return 0;
}

執行時間: 6 ms 使用記憶體: 11048 KB
這道題是道簡單的迴圈和分支結構練習題,只要加上之前每個月的天數和這個月過去的天數就行了。如果題目裡不提醒閏年判斷的話,可能正確率會下降很多。

288. 素數驗證碼

題目描述
密碼洩露的漏洞終於補上了。但是為了避免惡意猜測密碼,某網站推出了素數驗證碼(好弱的驗證碼……)。使用者需要判定網站給出的數字是否是素數。

輸入格式
一個數字,小於1000

輸出格式
是素數則輸出”YES“,否則輸出”NO“

輸入樣例
19

輸出樣例
YES

#include <stdio.h>
int ss(int t);
int main()
{
    int t;
    scanf("%d",&t);
    if(ss(t)) printf("YES");
    else printf("NO");
    return 0;
}
int ss(int t)//素數判定
{
    if(t==1||t==2||t==3) return 1;
    if(t%2==0) return 0;
    for(int i=3;i*i<=t;i++)
    {
        if(t%i==0) return 0;
    }
    return 1;
}

關於這道題,班裡dalao說打表(先算出1-1000的所有素數,然後判斷輸入地是不是素數)是最優方法。的確,在很多情況下,打表的確很節省時間。但我總覺得這道題裡打表不太合適,原因是這道題裡每次都是一次性的查詢,每次只查一個數,打的表第二次就不能再用了,這樣一來,就會有很多冗餘的計算和資料。
關於素數的判定,我所知道的最簡單的演算法就是上課時老師講的那種樸素演算法:判斷2—n-1中有沒有n的因子。還有一種耗時稍微少一點的演算法,也就是我使用的演算法:判斷2—sqrt(n)中有沒有n的因子(因為若n=a*b,那麼a、b中有且至少有一個,它的平方小於等於n)。還有幾種很有意思的基於概率的演算法,後面再講,這裡就不作詳述。