3.數(shù)組和字符串

內(nèi)容

數(shù)組

  1. 逆序輸出
    #include<stdio.h>
    #define maxn 1000000
    int a[maxn];
    
    int main()
    {
        int x, n=0;
        // 輸入
        while(scanf("%d", &x) == 1)
            a[n++] = x;
        // 輸出 
        for(int i=n-1; i>=1; i--){
            printf("%d ", a[i]);
        }
        printf("%d\n", a[0]);
        return 0;   
    }
    
    
    1. a[n++]玷或,首先賦值a[n]=x楔脯,然后執(zhí)行n=n+1
    2. 對于變量n挽懦,n++和++n都會給n加1态辛,但當它們用在一個表達式中時切黔,行為有所差別:n++會使用加1的值計算表達式,而++n會使用加1后的值計算表達式
    3. 比較大的數(shù)組盡量聲明在main函數(shù)外监署,否則程序可能無法運行
  2. 開燈問題
    n盞燈,第1個人把所有燈打開撵术,第2個人按下所有編號為2的倍數(shù)的開關(guān)(這些燈將被關(guān)掉),第3個人按下所有編號為3的倍數(shù)的開關(guān)(其中關(guān)掉的燈將被打開话瞧,開著的燈將被關(guān)掉)嫩与,依此類推。一共有k個人交排,問最后有哪些燈開著划滋?
    輸入n和k,輸出開著的燈的編號埃篓。k<=n<=1000处坪。
    #include<stdio.h>
    #include<string.h>
    #define maxn 1010
    int a[maxn];
    
    int main()
    {
        int n, k, first = 1;
        // 數(shù)組a初始化為0 
        memset(a, 0, sizeof(a));
        scanf("%d%d", &n, &k);
        // 模擬讓每個人去按開關(guān) 
        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]){
                // 輸出時第一個數(shù)字前無空格 
                if(first){
                    first = 0;
                }else{
                    printf(" ");
                }
                printf("%d", i);
            }
        }
        printf("\n");   
        return 0;   
    }
    
    memset(a, 0, sizeof(a));的作用是把數(shù)組初始化為0,定義在string.h中架专。
  3. 蛇形填數(shù)
    在nn方陣里填入1同窘,2,...胶征,nn,要求填成蛇形桨仿。n<=8睛低。
    #include<stdio.h>
    #include<string.h>
    #define maxn 20
    #define maxm 20
    int a[maxn][maxm];
    
    int main()
    {
        int n, x=0, y=0, tot = 0; 
        scanf("%d", &n);
        memset(a, 0, sizeof(a));
        tot = a[0][y=n-1] = 1;
        // 賦值過程 
        while(tot < n*n)
        {   
            // 先向下走 
            while(x+1<n && !a[x+1][y])
            {
                a[++x][y] = ++tot;
            }
            // 向左走 
            while(y-1>=0 && !a[x][y-1])
            {
                a[x][--y] = ++tot;
            }
            // 向上走 
            while(x-1>=0 && !a[x-1][y])
            {
                a[--x][y] = ++tot;
            }
            // 向右走 
            while(y+1<n && !a[x][y+1])
            {
                a[x][++y] = ++tot;
            }
        }
        // 輸出 
        for(x=0; x<n; x++)
        {
            for(y=0; y<n; y++)
                printf("%3d", a[x][y]);
            printf("\n");
        }
    
        return 0;   
    }
    
    這道題的思路值得好好思考。

字符數(shù)組

  1. 豎式問題
    #include<stdio.h>
    #include<string.h>
    
    int main()
    {
        int count = 0;
        char s[20], buf[99];
        scanf("%s", s);
        for(int abc=111; abc<=999; abc++)
        {
                for(int de=11; de<=99; de++)
                {
                int x = abc*(de%10), y = abc*(de/10), z = abc*de;
                sprintf(buf, "%d%d%d%d%d", abc, de, x, y, z);
                // 檢查每個字符是否都在輸入的集合
                int ok = 1;
                for(int i=0; i<strlen(buf); i++)
                {
                    if(strchr(s, buf[i]) == NULL)
                        ok = 0;
                } 
                if(ok)
                {
                    printf("<%d>\n", ++count);
                    printf("%5d\nX%4d\n-----\n%5d\n%4d\n-----\n%5d\n\n", abc, de, x, y, z);
                }
            }
        
        }
        printf("The number of solutions = %d\n", count);
        return 0;
     }
    
    模擬豎式計算服傍,但是必須豎式中所有的字符都必須屬于輸入的數(shù)字集合钱雷。
  2. 趣測試
    #include<stdio.h>
    #include<math.h>
    
    int main()
    {
        int count = 0;
        printf("%d %d %d", count++, count++, count++);
        return 0;
    }
    
     #include<stdio.h>

    int main()
    {
        int count = 0;
        count = count++;
        printf("%d", count);
        return 0;
    }

競賽題目選講

  1. Tex中的引號
    #include<stdio.h>
    
    int main()
    {
        int c, q=1;
        while((c = getchar()) != EOF)
        {
            if(c == '"')
            {
                printf("%s", q ? "``":"''");
                q = !q;
            }else{
                printf("%c", c);
            }
        }
        return 0;
    }
    
    getchar,讀取下一個字符吹零。
  2. WERTUYU
    輸入一個錯位后敲出的字符串罩抗,輸出打字員本來想打出的句子。輸入保證合法灿椅。
    #include<stdio.h> 
    char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
    
    int main()
    {
        int i,c;
        while((c = getchar()) != EOF)
        {
            for(i=1; s[i] && s[i] != c; i++);
            if(s[i]){
                putchar(s[i-1]);    
            }else{
                putchar(c);
            }
        }
        return 0;
    }
    
  3. 回文詞
    輸入一個字符串套蒂,判斷它是否為回文串以及鏡像串钞支。輸入字符串保證不含數(shù)字0。所謂回文串操刀,就是反轉(zhuǎn)以后和原串相同烁挟,如abba和madam。所有鏡像串骨坑,就是左右·鏡像之后和原串相同撼嗓,如2S和3AIAE。注意欢唾,并不是每個字符在鏡像之后都能得到一個合法字符且警。
    #include<stdio.h>
    #include<string.h>
    #include<ctype.h>
    // 每個字符的鏡像字符 A-Z 1-9 
    const char* rev = "A   3  HIL JM o   2TUVWXY51SE Z  8 ";
    // 輸出的結(jié)果 “不是回文串” “回文串” “鏡像串” “鏡像回文串” 
    const char* msg[] = {"not a palindrome", "a regular palindrome", "a mirrored string", "a mirrored palindrome"};
    
    char r(char ch) {
        // isalpha 判斷字符是否為字母  
        if(isalpha(ch)) {
            return rev[ch - 'A'];
        }
        return rev[ch - '0' + 25]; 
    }
    
    int main() {
        char s[30];
        while(scanf("%s", s) == 1) {
            // 字符串長度 
            int len = strlen(s);
            //  標志 
            int p = 1, m = 1;
            for(int i=0; i<(len+1)/2; i++) {
                //  是否是回文串 
                if(s[i] != s[len-1-i]) {
                    p = 0;
                }
                // 是否是鏡像串 
                if(r(s[i]) != s[len-1-i]) {
                    m = 0;
                }
            }
            printf("%s -- is %s.\n\n", s, msg[m*2+p]);
        }
        return 0;
    }
    
  4. 猜數(shù)字游戲的提示
    實現(xiàn)一個經(jīng)典“猜數(shù)字”游戲。給定答案序列和用戶猜的序列礁遣,統(tǒng)計有多少數(shù)字位置正確(A)斑芜,有多少數(shù)字在兩個序列都出現(xiàn)過但位置不對(B)。
    #include<stdio.h>
    #define maxn 1010
    
    int main() {
        int n, a[maxn], b[maxn];
        int kase = 0;
        while(scanf("%d", &n) == 1 && n) {
            printf("Game %d:\n", ++kase);
            // 輸入答案序列 
            for(int i =0 ; i<n; i++) {
                scanf("%d", &a[i]);
            }
            // 處理猜測序列 
            for(;;) {
                int A = 0, B = 0;
                // 求出位置正確的數(shù)字個數(shù)A 
                for(int i=0; i<n; i++) {
                    scanf("%d", &b[i]);
                    if(a[i] == b[i]) A++;
                }
                // 當猜測序列全為0退出 
                int sign = 1;
                for(int i=0; i<n; i++){
                    if(b[i] != 0){
                        sign = 0;
                        break;
                    } 
                }
                if(sign == 1) break;
                // 找到兩個序列都出現(xiàn)過的數(shù)字個數(shù)B 
                for(int d=1; d<=9; d++) {
                    int c1 = 0, c2 = 0;
                    for(int i = 0; i<n; i++) {
                        if(a[i] == d) c1++;
                        if(b[i] == d) c2++;
                    }
                    if(c1<c2) B += c1;
                    else B += c2;
                }
                // 輸出結(jié)果 
                printf("    (%d, %d)\n", A, B-A);
            }
        }
        return 0;
    }  
    
    這里做了一個小實驗亡脸,
    #include<stdio.h>
    #include<math.h>
    
    int main()
    {
        int count = 0;
        printf("%d \n", ++count);
        printf("%d \n", count);
        return 0;
    }
    
    result1

    再看下面這個程序運行結(jié)果押搪,

    #include<stdio.h>
    #include<math.h>
    
    int main()
    {
        int count = 0;
        printf("%d \n", count++);
        printf("%d \n", count);
        return 0;
    }
    
    result2
  5. 生成元
    如果x加上x的各個數(shù)字之和得到y(tǒng),就說x是y的生成元浅碾。給出n(1<=n<=100000)大州,
    求最小生成元。無解輸出0垂谢。例如厦画,n=216, 121滥朱,2005時的解分別為198根暑,0,1979徙邻。
    // 一次性枚舉
    #include<stdio.h>
    #include<string.h>
    #define maxn 100005
    int ans[maxn];
    
    int main() {
        int T, n;
        memset(ans, 0, sizeof(ans));
        for(int m=1; m < maxn; m++){
            int x = m, y = m;
            // 把x的每一位與x加起來 
            while(x > 0){
                y += x % 10;
                x /= 10;
            } 
            // 把最小的生成元保存下來 
            if(ans[y] == 0 || m < ans[y]){
                ans[y] = m;
            }
        }
        scanf("%d", &T);
        while(T--){
            scanf("%d", &n);
            printf("%d\n", ans[n]);
        }
        return 0;
    }
    
  6. 環(huán)狀序列
    長度為n的環(huán)狀串有n種表示法排嫌,分別為從某個位置開始順時針得到。在這些表示法中缰犁,字典序最小的稱為“最小表示”淳地。
    輸入一個長度為n(n<=100)的環(huán)狀DNA串(只包含A、C帅容、G颇象、T這4種字符)的額、一種表示法并徘,你的任務(wù)是輸出該環(huán)狀串的最小表示遣钳。
    #include<stdio.h>
    #include<string.h>
    #define maxn 105
    
    // 比較分別以p和q為開頭的序列 
    int less(const char* s, int p, int q){
        int n = strlen(s);
        for(int i= 0; i < n; i++){
            if(s[(p+i)%n] != s[(q+i)%n]){
                return s[(p+i)%n] < s[(q+i)%n];
            }
        }
        return 0; 
    } 
    
    int main(){
        int T;
        char s[maxn];
        // T個字符串 
        scanf("%d", &T);
        // 獲取輸入、處理字符串 
        while(T--){
            scanf("%s", s);
            // 到目前為止的標志 
            int ans = 0; 
            // 字符串的長度 
            int n = strlen(s);
            // 找到最小的字符 
            for(int i=1; i<n; i++){
                if(less(s, i, ans)) ans = i;
            }
            // 輸出最小表示 
            for(int i=0; i< n; i++){
                putchar(s[(i+ans)%n]);
            }
            putchar('\n');
        }
        return 0;
    }
    

練習

  1. 得分
    給出一個由O和X組成的串(長度為1~80)麦乞,統(tǒng)計得分蕴茴。每個O的得分為目前連續(xù)出現(xiàn)的O的個數(shù)劝评,X的得分為0。
    #include<stdio.h>
    #include<string.h>
    char s[82];
    
    int main() {
        int score=0;
        int sign1=0; 
        scanf("%s", s);
        int strength = strlen(s);
        for(int i=0; i<strlen(s); i++){
            if(s[i] == 'O'){
                sign1++;
            }else{
                sign1 = 0;
            } 
            score += sign1;
        }
        printf("%d", score);
        return 0;
    }
    
  2. 分子量
    給出一種物質(zhì)的分子式(不帶括號)荐开,求分子量付翁。本題中的分子式只包含4種原子,分別為C晃听、H百侧、O、N能扒,原子量分別為12.01佣渴,1.008,16.00初斑,14.01(單位:g/mol)辛润。例如,C6H5OH的分子量為94.108g/mol见秤。
    #include<stdio.h>
    #include<ctype.h>
    #include<string.h>
    char s[100];
    
    // 每個字母對應(yīng)的數(shù)值 
    double getNum(char r){
        double a = 0.0;
        if(r == 'C'){
            a = 12.01;
        }
        if(r == 'H'){
            a = 1.008;
        }
        if(r == 'O'){
            a = 16.00;
        }
        if(r == 'N'){
            a = 14.01;
        }
        return a;
    }
    
    int main(){
        scanf("%s", s);
        double all =0;
        // 循環(huán)遍歷 
        for(int i=0; i< strlen(s); i++){
            // 如果是一個字母 
            if(isalpha(s[i])){
                // 如果不是最后一個字符
                if(i+1 < strlen(s)){
                    // 如果下一個是數(shù)字 
                    if(!isalpha(s[i+1])){
                        // 那么相乘 
                        all += getNum(s[i])*(int)(s[i+1]-'0');
                        continue;
                    }else{
                        // 不是數(shù)字就不用乘 
                        all += getNum(s[i]);
                        continue;
                    }
                }else{
                    // 加上最后一個字符 
                    all += getNum(s[i]);
                    continue;
                }
            
            }
        }
        printf("%f\n", all);
        return 0;
    }
    
    記咨笆:字符數(shù)字轉(zhuǎn)整形數(shù)字的方法
  3. 數(shù)數(shù)字
    把前n(n<=10000)個整數(shù)順次寫在一起:123456789101112···數(shù)一數(shù)0~9各出現(xiàn)多少次,輸出10個整數(shù)鹃答。
    #include<stdio.h>
    #include<string.h>
    
    int a[10];
    char s[100005];
    
    int main() {
        scanf("%s", s);
        // 初始化數(shù)組 
        memset(a, 0, sizeof(a));
        // 獲得輸入串的實際長度 
        int n = strlen(s);
        // 賦值a數(shù)組 
        for(int i=0; i<n; i++) {
            int c = (int)(s[i]-'0');
            a[c]++;
        }
        // 輸出數(shù)組 
        for(int i=0; i<10; i++) {
            printf("%d ",a[i]);
        }
        return 0;
    }
    
  4. 周期串
    如果一個字符串可以由某個長度為k的字符串重復多次得到乎澄,則稱該串以k為周期。例如测摔,abcabcabcabc以3為周期(注意置济,它也以6和12為周期)
    輸入一個長度不超過80的字符串,輸出其最小周期锋八。
  5. 謎題
    一個5*5方格浙于,其中恰好有一個格子是空的,其他格子各有一個字母挟纱。一共有4種指令:A羞酗、B、L紊服、R檀轨,分別表示把空格上、下围苫、左裤园、右的相鄰字母移到空格中撤师。輸入初始網(wǎng)格和指令序列(以數(shù)字0結(jié)束)剂府,輸出指令執(zhí)行完畢后的網(wǎng)格。如有非法指令剃盾,應(yīng)輸出“This puzzle has no final configuration.”
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腺占,一起剝皮案震驚了整個濱河市淤袜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衰伯,老刑警劉巖铡羡,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異意鲸,居然都是意外死亡烦周,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門怎顾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來读慎,“玉大人,你說我怎么就攤上這事槐雾∝参” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵募强,是天一觀的道長株灸。 經(jīng)常有香客問我,道長擎值,這世上最難降的妖魔是什么慌烧? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮幅恋,結(jié)果婚禮上杏死,老公的妹妹穿的比我還像新娘。我一直安慰自己捆交,他們只是感情好淑翼,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著品追,像睡著了一般玄括。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肉瓦,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天遭京,我揣著相機與錄音,去河邊找鬼泞莉。 笑死哪雕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的鲫趁。 我是一名探鬼主播斯嚎,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了堡僻?” 一聲冷哼從身側(cè)響起糠惫,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钉疫,沒想到半個月后硼讽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡牲阁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年固阁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片城菊。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡您炉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出役电,到底是詐尸還是另有隱情赚爵,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布法瑟,位于F島的核電站冀膝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏霎挟。R本人自食惡果不足惜窝剖,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酥夭。 院中可真熱鬧赐纱,春花似錦、人聲如沸熬北。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讶隐。三九已至起胰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巫延,已是汗流浹背效五。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留炉峰,地道東北人畏妖。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像疼阔,于是被迫代替她去往敵國和親戒劫。 傳聞我的和親對象是個殘疾皇子适瓦,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容