EOJ 1199: http://acm.cs.ecnu.edu.cn/problem.php?problemid=1199
poj 1256: http://poj.org/problem?id=1256
题意不难理解:
给定一个字符串,让你完成:全排列+去重+排序;
最坑的是排序:poj 中有说明:
hint: An upper case letter goes before the corresponding lower case letter.
So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'.
按以上顺序,而不是ASCII码,貌似在这两句话中点到:
should be output in alphabetically ascending order.
An upper case letter goes before the corresponding lower case letter. (尽管我不觉得是这意思。。。)
思路:在全排列前先排序,并在经典的生成全排列的基础上加上去重;
经典的全排列算法有两种:(都是dfs)
1.基于交换。
2.基于填表。
此处用的是后者。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <algorithm> 5 #include <string.h> 6 #include <stdlib.h> 7 8 using namespace std; 9 int n; 10 char s[1000]; 11 char out[1000]; 12 int v[1000]; 13 14 bool cmp(const char& a, const char &b) 15 { 16 return (tolower(a) == tolower(b))? 17 a < b: tolower(a) < tolower(b); 18 } 19 20 void dfs(int depth) 21 { 22 if(depth == n) 23 { 24 out[depth] = '\0'; 25 printf("%s\n", out); 26 return ; 27 } 28 for(int i=0; i<n; i++) 29 { 30 if(!v[i]) 31 { 32 v[i] = 1; 33 out[depth] = s[i]; 34 dfs(depth + 1); 35 v[i] = 0; 36 37 while(i<n-1 && s[i] == s[i+1]) 38 i++; //去重部分 39 } 40 } 41 } 42 43 int main() 44 { 45 //freopen("testin.txt", "r", stdin); 46 //freopen("testout.txt", "w", stdout); 47 48 int t; 49 cin >> t; 50 while(t--) 51 { 52 scanf("%s", s); 53 n = strlen(s); 54 55 sort(s, s+n, cmp);//按照cmp排序 56 memset(v, 0, sizeof(v)); 57 dfs(0); 58 //cout << endl; 59 } 60 61 return 0; 62 }
解法2:
找到最小的序列,接下来的操作类似——从1数到100(自然不会重复)。
须调用库函数 next_permutation();(STL果然变态)。
在<algorithm>里
next_permutation(); 有两种重载方式(类似sort):
带cmp和不带cmp;
函数原型:
template<class BidirectionalIterator>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last
);
template<class BidirectionalIterator, class BinaryPredicate>
bool next_permutation(
BidirectionalIterator _First,
BidirectionalIterator _Last,
BinaryPredicate _Comp
);
废话少说,上代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <algorithm> 5 #include <string.h> 6 #include <stdlib.h> 7 8 using namespace std; 9 int io, n; 10 char s[1000]; 11 bool cmp(const char& a, const char& b) 12 { 13 return (tolower(a) == tolower(b))? 14 a < b: tolower(a) < tolower(b); 15 } 16 17 int main() 18 { 19 //freopen("testin.txt", "r", stdin); 20 //freopen("testout.txt", "w", stdout); 21 22 int t; 23 cin >> t; 24 while(t--) 25 { 26 scanf("%s", s); 27 n = strlen(s); 28 sort(s, s+n, cmp); 29 30 printf("%s\n", s); 31 while(next_permutation(s, s+n, cmp)) 32 printf("%s\n", s); 33 //cout << endl; 34 } 35 36 return 0; 37 }