Anagram poj-1256
题目大意:给你n个字符串,求每一个字符串所有字符的全排列,按照顺序输出所有全排列。
注释:每一个字符长度小于13,且字符排序的顺序是:A<a<B<b<C<c<...<Y<y<Z<z
想法:哇塞,我是读完了题,完全码完了之后才发现顺序不是字典序的... ...悲催。这题是一道挺有意思的全排列的题,这题其实需要我们去掉重复的字符。不然的话,输出的全排列会有明显的重复,我们在这里用结构体离散化整个字符串,将每个字符存进一个结构体,同样的,结构体里还有这个字符的出现次数。dis[s[i]-'0']表示s[i]这个字符在dis[s[i]-'0']个结构体里。然后就是最经典的这道题的好玩儿的地方——compare函数(cmp)。附上丑陋的cmp函数
1 struct Node 2 { 3 char change;//change表示这个结构体所代表的字符 4 int sum;//sum表示这个字符所出现的次数 5 }f[10010]; 6 bool cmp(Node x, Node y) 7 { 8 char a=x.change; 9 char b=y.change; 10 if(a<='Z'&&b<='Z') 11 return a<b; 12 else if(a>='a'&&b>='a') 13 return a<b; 14 else if(a>='a'&&b<='Z') 15 return a-'a'<b-'A'; 16 else if(b>='a'&&a<='Z') 17 return a-'A'<=b-'a'; 18 }
然后,就是一些“小”问题了,都是细节啊!!
最后,附上丑陋的代码... ...
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 char ans[20]; 7 int dis[150]; 8 int k; 9 int cnt; 10 char s[20]; 11 struct Node 12 { 13 char change;//change表示这个结构体所代表的字符 14 int sum;//sum表示这个字符所出现的次数 15 }f[10010]; 16 bool cmp(Node x, Node y) 17 { 18 char a=x.change; 19 char b=y.change; 20 if(a<='Z'&&b<='Z') 21 return a<b; 22 else if(a>='a'&&b>='a') 23 return a<b; 24 else if(a>='a'&&b<='Z') 25 return a-'a'<b-'A'; 26 else if(b>='a'&&a<='Z') 27 return a-'A'<=b-'a'; 28 } 29 void dfs(int a)//表示当前正在填充全排列其中一个排列的第a个字符 30 { 31 if(a==k+1)//退出条件 32 { 33 printf("%s ",ans+1);//ans数组存的是生成的全排列 34 return; 35 } 36 for(int i=1;i<=cnt;i++) 37 { 38 if(f[i].sum) 39 { 40 ans[a]=f[i].change; 41 f[i].sum--; 42 dfs(a+1); 43 f[i].sum++;//回溯! 44 } 45 } 46 } 47 int main() 48 { 49 int cases; 50 scanf("%d",&cases); 51 while(cases--) 52 { 53 memset(dis,0,sizeof(dis)); 54 memset(ans,0,sizeof(ans)); 55 cnt=0; 56 for(int i=1;i<=1010;i++) f[i].sum=0; 57 scanf("%s",s+1); 58 k=strlen(s+1); 59 for(int i=1;i<=k;i++) 60 { 61 if(!dis[s[i]-'0']) 62 { 63 dis[s[i]-'0']=cnt+1; 64 cnt++; 65 f[cnt].change=s[i]; 66 } 67 f[dis[s[i]-'0']].sum++; 68 } 69 sort(f+1,f+cnt+1,cmp); 70 dfs(1); 71 } 72 return 0; 73 }
小结:注意dis数组表示的是什么,我一直都给赋值成了1... ...