1題:WERTYU(競賽基礎題)
把手放在鍵盤上時,稍不注意就會往右錯一位,這樣的話Q會變為W,J會變為K等。輸入一個錯位後敲出的字符串,輸出打字員本來想打出的句子。
樣例輸入:O S, GOMR YPFSU/
樣例輸出:I AM FINE TODAY.
1 #include <stdio.h>
2 const char *str = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
3
4 int main(void)
5 {
6 char c;
7 int i;
8 while ((c = getchar()) != EOF)
9 {
10 for (i = 0; str[i] && str[i] != c; i++);
11 if (str[i])
12 putchar(str[i - 1]);
13 else
14 putchar(c);
15 }
16
17 return 0;
18 }
解析:本題注意兩點:(1)for循環終止條件的判斷,常量字符串末尾自動補“\0”,因而可利用str[i]的取值判斷是否查找到最後一個字符。(2)反斜線“\”是特殊字符,需要使用轉義序列或直接引用其ASCII碼。
2題:TeX括號(競賽基礎題)
在TeX中,左雙引號是``,右雙引號是’’。輸入一篇包含雙引號的文章,你的任務是把它轉換成TeX格式。
樣例輸入:
“To be or not to be,” quoth the Bard, “thatis the question”.
樣例輸出:
``To be or not to be,” quoth the Bard,``that is the question”.
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char c;
6 int q = 1;
7 while ((c = getchar()) != EOF)
8 {
9 if (c == '"')
10 {
11 printf("%s", q ? "``" : "''");
12 q = !q;
13 }
14 else
15 printf("%c", c);
16 }
17
18 return 0;
19 }
解析:本題的關鍵是如何判斷一個雙引號是左雙引號還是右雙引號。
3題:周期串(競賽基礎題)
如果一個字符串可以由某個長度為k的字符串重復多次得到,我們說該串以k為周期。例如,abcabcabcabc以3為周期(注意,它也以6和12為周期)。輸入一個長度不超過80的串,輸出它的最小周期。
樣例輸入:HoHoHo
樣例輸出:2
寫法1:
1 #include <stdio.h>
2 #include <string.h>
3 #define MAXLEN 80
4 int main(void)
5 {
6 char str[MAXLEN + 1] = {0};
7 scanf("%s", str);
8 int len = strlen(str);
9 int result = len;
10 int i, j;
11
12 for (i = 1; i < len / 2 + 1; i++) //i為周期
13 {
14 for (j = 0; j < len - i; j++)
15 {
16 if (str[j] != str[j + i])
17 break;
18 }
19
20 if (j == len - i)
21 {
22 result = i;
23 break;
24 }
25 }
26 printf("%d\n",result);
27
28 return 0;
29 }
寫法2:
1 #include <stdio.h>
2 #include <string.h>
3 int main(void)
4 {
5 char word[100];
6 scanf("%s", word);
7 int len = strlen(word);
8 int i, j;
9
10 for (i = 1; i <= len; i++)
11 {
12 if (len % i == 0)
13 {
14 int ok = 1;
15 for (j = i; j < len; j++)
16 if (word[j] != word[j % i])
17 {
18 ok = 0;
19 break;
20 }
21 if (ok)
22 {
23 printf("%d\n", i);
24 break;
25 }
26 }
27 }
28
29 return 0;
30 }
解析:本題兩種解法的思路是一致的。
4題:編寫一個函數,把一個char組成的字符串循環右移n位。例如:原來是”abcdefghi”,如果n = 2,移位後應該是”hiabcdefg”。(面試題)
1 #include <stdio.h>
2 #include <string.h>
3 #define MAX_LEN 1024
4
5 void LoopMove_1(char *pStr, int steps)
6 {
7 int len = strlen(pStr) - steps;
8 char temp[MAX_LEN];
9
10 strcpy(temp, pStr + len);
11 strcpy(temp + steps, pStr);
12 *(temp + steps + len) = '\0';
13 strcpy(pStr, temp);
14 }
15
16 void LoopMove_2(char *pStr, int steps)
17 {
18 int len = strlen(pStr) - steps;
19 char temp[MAX_LEN];
20
21 memcpy(temp, pStr + len, steps);
22 memcpy(temp + steps, pStr, len);
23 memcpy(pStr, temp, len + steps);
24 }
25
26 int main(void)
27 {
28 char str1[] = "abcdefghi";
29 LoopMove_1(str1, 3);
30 printf("%s\n", str1);
31
32 char str2[] = "gklmnopqrst";
33 LoopMove_1(str2, 3);
34 printf("%s\n", str2);
35 return 0;
36 }
解析:本題提供了兩種方法。
5題:編寫程序,從鍵盤輸入一組任意長度的字符串,當輸入“#”符時結束輸入(字符串不包括“#”),然後程序反向輸出該字符串。(面試題)
方法1:將輸入的字符串保存在一個數據結構中,然後將其內容反向輸出。例如:首先申請一個棧,每輸入一個字符時都將該字符做入棧操作,直到入棧隊列中發現“#”為止(“#”不入棧)。然後再將棧中的元素順序出棧。
1 #include <stdio.h>
2 #define MAX_LEN 1024
3
4 int main(void)
5 {
6 char arr[MAX_LEN], c;
7 int i = 0, j;
8 while ((c = getchar()) != '#')
9 {
10 arr[i++] = c;
11 }
12 arr[i] = '\0';
13
14 for (j = i - 1; j >= 0; j--)
15 {
16 printf("%c", arr[j]);
17 }
18 printf("\n");
19
20 return 0;
21 }
方法2:題目沒要求保存輸入的字符串,因此可用遞歸解此題。遞歸算法本身有棧的特性,每次遞歸地調用遞歸函數時,系統都會將現場保存在棧中,待調用結束返回時再恢復現場的內容。
1 #include <stdio.h>
2
3 void StrRev()
4 {
5 char c;
6 scanf("%c", &c);
7 if ('#' == c)
8 {
9 printf("反轉後的字符串:");
10 return;
11 }
12
13 StrRev();
14 printf("%c", c);
15 }
16
17 int main(void)
18 {
19 printf("請輸入英文字符串(以#結束):");
20 StrRev();
21 printf("\n");
22 return 0;
23 }