题解:
去掉输入过程中重复的单词,需要对统一小写后的单词排序,例如 aab cdf frf aab AaB,小写排序后是aab aab aab cad frf,那么很容易遍历一遍进行标记,将输入重复的单词只保留一个。
寻找回文,例如adc cda utg 三个单词,对每一个单词进行字母排序后再整体排序,排序结果是:acd acd gtu ,出现次数大于一次的很显然是回文, 那么和上面一样,很容易遍历2遍后将出现次数大于一次的单词去掉。最后剩下的就是非回文。然后对非回文进行排序输出即可。
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
|
#
include
<iostream>
#
include
<cstdio>
#
include
<string>
#
include
<cstring>
#
include
<algorithm>
#
include
<cctype>
using
namespace
std;
string ss[
10000
];
char s[
100
];
int
k,k2,tag[ 10000 ];
struct Node{
string ori,low,sor;
//ori原始输入,low小写处理,sor字母排序
}str[
10000
];
bool cmp1(Node a,Node b){
//按照小写后单词进行排序处理
return
a.low < b.low;
}
bool cmp2(Node a,Node b){
//按照字母排序后的单词排序处理
return
a.sor < b.sor;
}
void
set (Node&b,Node&a){ //赋值操作
b.ori = a.ori;b.low = a.low;b.sor=a.sor;
}
int
main(){
//freopen("1.in","r",stdin);
while
(scanf(
"%s"
,s)!=EOF && s[
0
]!=
'#'
){
str[k].ori = s;
for
(
int
i= 0 ;s[i];i++)s[i]=tolower(s[i]);
str[k].low = s ;
//小写
sort(s,s+strlen(s));
str[k++].sor = s;
//排序
}
//对小写后的单词进行排序,目的是去除输入过程中重复的单词
sort(str,str+k,cmp1);
string pre =
""
;
for
(
int
i= 0 ;i<k;i++){
if
(str[i].low == pre)tag[i]=
1
;
pre = str[i].low;
}
for
(
int
i= 0 ;i<k;i++){
if
(!tag[i])
set
(str[k2++],str[i]);
else
tag[i]= 0 ;
}
//对字母排序后的单词排序,目的是寻找回文单词
k = k2;
sort(str,str+k,cmp2);
pre =
""
;
for
(
int
i= 0 ;i<k;i++){
if
(str[i].sor == pre)tag[i]=
1
;
pre = str[i].sor;
}
for
(
int
i= 0 ;i<k;i++)
if
(tag[i])tag[i-
1
]=
1
;
k2=
0
;
for
(
int
i= 0 ;i<k;i++)
if
(!tag[i])ss[k2++]=str[i].ori;
//最后对原始输入排序输出。
sort(ss,ss+k2);
for
(
int
i= 0 ;i<k2;i++)
cout << ss[i]<<endl;
}
|