巧用數組

例題引入:
把手放在鍵盤上,稍不留意就會往右錯移一位。這樣輸入的Q就會變成輸入W;輸入的J就會變成輸入K等。問題:輸入一個錯位後的字符串(大寫),輸出打字員本來想打的句子。假定前提:輸入保證合法(例如:輸入中不會出現A)
樣例輸入:
O S, GOMR YPFSU/
樣例輸出:
I AM FINE TODAY.
分析:
1.輸入字符串(包括輸入空格)可以用getchar
2.輸入輸出轉換:法一:可以使用if語句或者switch語句,如:“if(c==’W’) putchar(‘Q’)”。但這樣做,太麻煩了。
可以換一種思路,用常量數組儲存字符,輸出原來字符的前一個。
(ps:常量數組不需要指明大小,編譯器會計算)
以下是參考代碼:

#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);
    }
}

另一經典例題:判斷迴文串&鏡像串
題目:輸入一個字符串,判斷它是否爲迴文串以及鏡像串,每組數據後輸出一個空行。輸入的字符保證不含數字0。所謂字符串,就是反轉後和原串相同,如:abba,madam.
所謂鏡像串,就是左右鏡像之後和原串相同,如2S,3AIAE。注意:並不是每個字符在鏡像之後都能得到一個合法字符。在 本題中,每個字符的鏡像如下圖所示(空白項表示該字符鏡像後不能得到一個合法的字符):鏡像轉換

樣例輸入:
NOTAPALINDROME
ISAPALINILAPASI
2A3MEAS
ATOYOTA
樣例輸出:
NOTAPALINDROME–is not a palindrome.
ISAPALINILAPASI–is a regular palindrome.
2A3MEAS–is a mirrored string.
ATOYOTA–is a mirrored palindrome.
獻上代碼:

#include<stdio.h>
#include<string.h>
#include<ctype.h>
const char* rev = "A   3  HIL J M O   2TUVWXY51SE Z  8 ";
const char* msg[] = { "not a palindrome","a regular palindrome","a mirrored string","a mirrored palindrome" };
char r(char ch)
{
    if (isalpha(ch)) return rev[ch - 'A'];
    else return rev[ch - '0' + 25];
}
int main()
{
    char s[30];
    while (scanf("%s",s)==1)
    {
        int len = strlen(s);
        int p = 1, m = 1;
        int i;
        for ( 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;
}

例題引入(出自UVA 340):
經典“猜數字”遊戲,給定答案數列和用戶猜的數列,統計有多少數字位置正確(A),有多少位置在兩個序列都出現過但位置不對(B).
輸入包含多組數據,每組輸入第一行爲序列長度n,第二行是答案序列,接下來是若干猜測數列。當猜測數列全爲0時數據結束,n=0時輸入結束。
樣例輸出:
4
1 3 5 5
1 1 2 3
4 3 3 5
6 5 5 1
6 1 3 5
1 3 5 5
0 0 0 0
10
1 2 2 2 4 5 6 6 6 9
1 2 3 4 5 6 7 8 9 1
1 1 2 2 3 3 4 4 5 5
1 2 1 3 1 5 1 6 1 9
1 2 2 5 5 5 6 6 6 7
0 0 0 0 0 0 0 0 0 0
0
輸出案例:
Game 1:
(1,1)
(2,0)
(1,2)
(1,2)
(4,0)
Game 2:
(2,4)
(3,2)
(5,0)
(7,0)

獻上我自己想的代碼(有bug):

#include <stdio.h>
#define MAXN 1010
int main()
{
    int n,i,j;
    int ans[MAXN],guess[MAXN];
    int cnt=1;
    printf("Game %d:\n",cnt++);
    while(scanf("%d",&n) && n)
    {
        for(i=0;i<n;i++)
            scanf("%d",&ans[i]);
        while(1)
        {
            for(i=0;i<n;i++)
                scanf("%d",&guess[i]);
            if(guess[0]==0) break;
            int a=0,b=0;
            for(i=0;i<n;i++)
            {
                if(guess[i]==ans[i]) a++;
                for(j=0;j<n;j++)
                    if(guess[i]==ans[j] && i != j)
                    {
                        b++;
                        break;
                    }

            }
            if(a==n) b=n;
            printf("(%d,%d)\n",a,b-a);
        }
    }
    return 0;
}

錯誤分析:首先在理解題目上就有一點小問題,題目的隱含着
兩列中任意一個元素如果已經用過就不能再用了。
題意簡單一點理解就是:

如果給出的數字和猜測的數字一樣,並且在同一列上(即:i==j)那麼就是括號左邊的數字加1.即a=a+1
如果位置不一樣,數字一樣,則b=b+1;

最後計算b的思路爲:
因爲只有9個數字,所以只需要統計每個數字出現的個數。先把同一列相同數字的統計一遍,即相同列相同數字對應的個數減一。然後統計9個數字在兩序列中出現的個數,每個數字加其再兩個序列中出現個數的較小值。
AC代碼可參考:
http://blog.csdn.net/zcube/article/details/8461796#comments
http://blog.csdn.net/oceaniwater/article/details/7947558

發佈了47 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章