Codebar 程式酒吧

一座輕鬆學習程式的酒吧

0%

a224. 明明愛明明

題目連結

https://zerojudge.tw/ShowProblem?problemid=a224

建議類題

a022. 迴文

解題思路

本題乍看之下就是單純判斷輸入字串是否為迴文,但須注意本題對迴文的定義是「只要重新安排順序後,符合迴文條件就算迴文」,也就是說字串的在輸入時的排列順序未必與可以形成迴文的順序相同。因此我們不能用當時a022. 迴文的想法,直接頭尾一組檢查字元是否相同,必須換種作法才行。

根據定義,迴文字串必定頭尾對稱,換句話說最多只能有一種字母出現奇數次。因此,我們可以藉由檢查測資中各字母出現的次數,來判斷重新排列後是否可以形成迴文字串。若有一種以上的字母出現奇數次則非迴文;而若是26個字母檢查完接皆未出現上述情況則為迴文。

注意事項

在了解如何判斷迴文字串後,本題還有另兩點需要注意。
第一,本題的測資夾雜了非英文字母的字元,在判斷時需將這些字元忽略。
第二,大寫和小寫字母在本題視為相同,在判斷字母出現次數時須特別注意。

程式碼:C語言

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdio.h>
int main() {
//宣告字元陣列input,並以字串形式讀取,代表輸入的測資
char input[1000];
//使用EOF寫法判斷程式執行的條件
while(scanf("%s", input) != EOF) {
//宣告陣列alphabet,代表各個英文字母出現的次數(不分大小寫)
//宣告變數num,代表出現次數為偶數的英文字母數量
//宣告變數test,代表是否為迴文字串
int alphabet[26] = {}, num = 0, test = 1;
//逐一判斷輸入字元為何,計算各個英文字母出現的次數
for(int i = 0 ; input[i] != '\0' ; i ++)
switch(input[i]) {
case 65: //檢查A
case 97: //檢查a
alphabet[0] ++;
break;
case 66: //檢查B
case 98: //檢查b
alphabet[1] ++;
break;
case 67: //檢查C
case 99: //檢查c
alphabet[2] ++;
break;
case 68: //檢查D
case 100: //檢查d
alphabet[3] ++;
break;
case 69: //檢查E
case 101: //檢查e
alphabet[4] ++;
break;
case 70: //檢查F
case 102: //檢查f
alphabet[5] ++;
break;
case 71: //檢查G
case 103: //檢查g
alphabet[6] ++;
break;
case 72: //檢查H
case 104: //檢查h
alphabet[7] ++;
break;
case 73: //檢查I
case 105: //檢查i
alphabet[8] ++;
break;
case 74: //檢查J
case 106: //檢查j
alphabet[9] ++;
break;
case 75: //檢查K
case 107: //檢查k
alphabet[10] ++;
break;
case 76: //檢查L
case 108: //檢查l
alphabet[11] ++;
break;
case 77: //檢查M
case 109: //檢查m
alphabet[12] ++;
break;
case 78: //檢查N
case 110: //檢查n
alphabet[13] ++;
break;
case 79: //檢查O
case 111: //檢查o
alphabet[14] ++;
break;
case 80: //檢查P
case 112: //檢查p
alphabet[15] ++;
break;
case 81: //檢查Q
case 113: //檢查q
alphabet[16] ++;
break;
case 82: //檢查R
case 114: //檢查r
alphabet[17] ++;
break;
case 83: //檢查S
case 115: //檢查s
alphabet[18] ++;
break;
case 84: //檢查T
case 116: //檢查t
alphabet[19] ++;
break;
case 85: //檢查U
case 117: //檢查u
alphabet[20] ++;
break;
case 86: //檢查V
case 118: //檢查v
alphabet[21] ++;
break;
case 87: //檢查W
case 119: //檢查w
alphabet[22] ++;
break;
case 88: //檢查X
case 120: //檢查x
alphabet[23] ++;
break;
case 89: //檢查Y
case 121: //檢查y
alphabet[24] ++;
break;
case 90: //檢查Z
case 122: //檢查z
alphabet[25] ++;
break;
}

for(int i = 0 ; i < 26 ; i ++) {
//若有一種以上的字母出現奇數次,則非迴文
if(alphabet[i]%2 == 1)
num ++;
if(num == 2) {
printf("no...\n");
test = 0;
break;
}
}
//若26個字母檢查完接皆未出現上述情況,則為迴文
if(test == 1)
printf("yes !\n");
}
return 0;
}