「算法競賽入門經典 第二版」第 3 章 數組和字符串 習題解答

關于 輸入 問題的注意:

  • 數組在main函數中的定義的無法定義的很大,所以大數據的數組一般定義在main函數外面
  • scanf("%s") 碰到 "\0"、空格、TAB 會停止
  • fgetc(fin) 讀取一個打開的文件 fin 碰到 EOF 會停止
    EOF 并不是char類型,因此 fgetc不會返回 char,而是返回 int類型
  • getchar() 從標準輸入讀取一個字符 == fgetc(stdin)
    Windows 回車符:"\r\n" Windows下讀取次回車符,fgetc、getchar 只讀取 "\n"
    Linux 回車符:"\n" Linux 下讀取Win的回車符,fgetc、getchar 會讀取 "\r\n"
    MacOS 回車符:"\r" 同 Linux
  • fgets(buf, maxn, fin) 碰到 "\n"、EOF 會停止
    buf 的聲明為 char buf[maxn] fgets函數讀取不超過 maxn-1個字符,然后在末尾添加 "\0"
    一個字符都沒有讀到時 fgets 返回 NULL
  • gets(s) 碰到 "\n"、EOF 會停止
    從標準輸入中讀取字符串,但 沒有指明讀取的最大字符數
    會不停的往 s 存儲內容,不管是否存儲的下「存在緩沖區溢出漏洞」
    C11標準里 gets函數已經刪除

3-1 「UVa1585」得分:給出一個由O和X組成的串(長度為1~80),統計得分。每個O得分為目前連續出現的O的個數,X得分為0.例如,OOXXOXOOOX的得分為 1+2+0+0+1+0+0+1+2+3

#include<stdio.h>
#define MAX 100
int main() {
    char str[MAX];
    scanf("%s", str);
    int sum,cO;
    sum=cO=0;
    for (int i=0; str[i]!='\0'; i++){
        if (str[i]=='O'){
            cO++;
            sum += cO;
            printf("%d", cO);
        }else{
            cO=0;
            printf("%d", 0);
        }
        
        if(str[i+1]!='\0'){
            printf("+");
        }else{
            printf("=");
        }
    }
    printf("%d\n", sum);
    return 0;
}

3-2 「UVa1586」分子量:給出一種物質的分子式(不帶括號)求分子量。本題分子只包含4種原子,分別為C,H,O,N 分子量為分別為12.01,1.008,16.00,14.01(單位:g/mol)例如:C6H5OH 的分子量為 94.108g/mol

#include<stdio.h>
#include<string.h>
#include<ctype.h>//int isdigit(int,char)需要的頭文件
#define MAX 20
double getWeight(char c){
    double w = 0;
    switch (c) {
        case 'c':
        case 'C': w = 12.01;break;
        case 'h':
        case 'H': w = 1.008;break;
        case 'o':
        case 'O': w = 16.00;break;
        case 'n':
        case 'N': w = 14.01;break;
    }
    return w;
}
int main() {
    char str[MAX];
    scanf("%s", str);
    if(isdigit(str[0])){//isdigit判斷字符是不是數字
        printf("輸入格式錯誤!\n");
        return 0;
    }
    double weight = 0;
    double sum = 0;
    for (int i=0; i<strlen(str);i++){
        int num = 1;
        for(int pre=0; isdigit(str[i]);i++){
            num = pre*10+str[i]-'0';
            pre = num;
        }
        sum += num * weight;   //weight = str[i-1]'s weight
        if(i<strlen(str)) weight = getWeight(str[i]);  //weight = str[i]'s weight
    }
    sum += weight;//加上最后一次循環的原子量
    printf("分子量為:%.3lfg/mol\n", sum);
    return 0;
}

3-3「UVa1225」數數字:把前n(n<=1000)個整數順次寫在一起:89101112...數一數09各出現多少次(輸出10個整數,分別是09出現的次數)

#include<stdio.h>
#include<string.h>
#define MAX 1000000
char str[MAX];
// windows下獨有一個 char *ito(int 要轉換的數,char *轉換后的數組位置,int 轉換后的進制數) 函數
// 它在 stdlib.h 中,是 將數字轉化為字符串 的函數
void itoa(int n,char *s){
    int sign;
    char tmp[100];
    if((sign=n)<0)//記錄符號
        n=-n;//使n成為正數
    int i=0;
    do{
        tmp[i++]=n%10+'0';//取下一個數字
    }while((n/=10)>0);//刪除該數字
    if(sign<0) tmp[i++]='-';
    for(int j=i-1,k=0; j>=0; j--,k++)//生成的數字是逆序的,所以要逆序輸出
        s[k] = tmp[j];
    s[i]='\0';
}
int main() {
    int n;
    scanf("%d",&n);
    int count[10]={0};//每個標號存儲對應的數字出現的次數
    char tmp[10];
    for (int i=n; i<=10000; i++) {
        itoa(i, tmp);
        strcat(str,tmp);//將字符串tmp添加到str后面,并返回添加后的數組
    }
    for(int i=0; i<strlen(str); i++)
        count[str[i]-'0']++;
    for (int i=0; i<10; i++)
        printf("Times of %d is %d\n",i,count[i]);
    
    return 0;
}
//注:本題也可直接根據數學方法求出,不過公式的推導較浪費時間,方法不在列出

3-4「UVa455」周期串:如果一個字符可以由某個長度為k的字符串重復多次得到,則稱該串以k為周期。例如:abcabcabcabc 以3為周期(注意:它也以6和12為周期)輸入一個長度不超過80的字符串,輸出其最小周期。

#include<stdio.h>
#include<string.h>
#define MAX 80
int main() {
    char str[MAX];
    scanf("%s",str);
    int len = strlen(str);
    for (int i=1; i<len; i++){
        if (len%i == 0){ //如果i為最小周期,那么字符串長度必定是i的整數倍
            int flag = 1;
            for (int j=i; j<len; j++)  //判斷數組是否已i為周期
                if (str[j-i] != str[j]) flag = 0;
                else break;
            if (flag){
                printf("最小周期為:%d \n",i); //輸出對應的周期
                break; //如果flag不為0,那么退出循環
            }
        }
    }
    return 0;
}

開燈問題:有n盞燈,編號為1~n。第1個人把所有燈打開,第2個人按下所有編號為2的倍數的開關(這些燈將被關掉),第3個人按下所有編號為3的倍數的開關(其中關掉的燈將會打開,打開的燈將會關掉),依次類推。一共有k個人,問最后有那些燈開著?輸入n和k,輸出 開著 的燈的編號。k<=n<=10000
樣例輸入
7 3
樣例輸出
1 5 6 7

#include<stdio.h>
#include<string.h>//memset
#define MAX 1010
int a[MAX];
int main()
{
    int n, k, first=1;
    memset(a,0,sizeof(a));//把數組清 0
    scanf("%d%d",&n,&k);
    for(int i=1; i<=k; i++)
        for(int j=1; j<=n; j++)
            if(j%i == 0) a[j] = !a[j];
    for(int i=1; i<=n; i++)
        if(a[i]){
            if(first) first=0;//避免輸出多余空格
            else printf(" ");
            printf("%d", i);
        }
    printf("\n");
    return 0;  
}

蛇形填數:在nxn方陣里填入1,2,3,...,nxn,要求填成蛇形。例如:n=4時的方陣為:「下面方陣,多余的 '_' 只是為了便于觀察,不必嚴格輸出,n<=8」
10 11 12 1
_9 _6 13 2
_8 15 14 3
_7 _6 _5 4

#include<stdio.h>
#define MAXN 50
int main()
{
    int a[MAXN][MAXN]={0};//給數組清0
    int num,n,x,y;
    scanf("%d",&n);
    num = a[x=0][y=n-1] = 1;
    while(num < n*n){
        while(x+1<n && !a[x+1][y]) a[++x][y] = ++num;
        while(y-1>=0 && !a[x][y-1]) a[x][--y] = ++num;
        while(x-1>=0 && !a[x-1][y]) a[--x][y] = ++num;
        while(y+1<n && !a[x][y+1]) a[x][++y] = ++num;
    }
    for(x=0; x<n; x++){
        for(int y=0; y<n; y++)
            printf("%5d",a[x][y]);
        printf("\n");
    }
    return 0;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,238評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,430評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,134評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,893評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,653評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,136評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,212評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,372評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,888評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,738評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,482評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,179評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,588評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,829評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,610評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,916評論 2 372

推薦閱讀更多精彩內容