//枚举
简单递归全排列
#include <cstdio> int a[100]; int n; void premutation(int n,int* a,int cur) { if(cur == n) { for(int i = 0; i < n; i++) printf("%d",a[i]); printf("\n"); return; } for(int i = 0; i < n; i++) { int ok = 1; for(int j = 0; j < cur; j++) if(a[j] == i) //判断是否当前已选过 ok = 0; if(ok) {a[cur] = i; premutation(n,a,cur+1);} } } int main() { scanf("%d",&n); premutation(n,a,0); return 0; }
//输入数组p,按字典序输出数组a各元素的所有全排列
有输入递归全排列
#include <cstdio> const int Max = 10000; int n,a[Max],p[Max]; void permutation(int n,int* p,int* a,int cur) { if(cur == n) { for(int i = 0; i < n; i++) printf("%d",a[i]); printf("\n"); } else for(int i = 0; i < n; i++) { int ok = 1; for(int j = 0; j < cur; j++) if(a[j] == p[i]) ok = 0; if(ok) { a[cur] = p[i]; permutation(n,p,a,cur+1); } } } int main() { scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&p[i]); permutation(n,p,a,0); return 0; }
若p中有元素重复,则没有输出,所以需要
//输入数组p,按字典序输出数组a各元素的所有全排列 #include <cstdio> const int Max = 10000; int n,a[Max],p[Max]; void permutation(int n,int* p,int* a,int cur) { if(cur == n) { for(int i = 0; i < n; i++) printf("%d",a[i]); printf("\n"); } else for(int i = 0; i < n; i++) if(!i || p[i]!=p[i-1]) //因为p是排好序的,所以只对每个相同元素组做一次递归,并控制输出相同元素个数 { int c1 = 0, c2 = 0; for(int j = 0; j < cur; j++) if(a[j] == p[i]) c1 ++; for(int j = 0; j < n; j++) if(p[j] == p[i]) c2 ++; if(c1 < c2) { //当前a中p[i]比p中的少,控制a中相同元素的个数,若某个数出现n次,最多定位到n-1的时候还能够继续递归 a[cur] = p[i]; permutation(n,p,a,cur+1); } } } int main() { scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&p[i]); permutation(n,p,a,0); return 0; }
用STL库函数next_permutation直接枚举,适用于可重集
//输入数组p,按字典序输出数组a各元素的所有全排列 #include <cstdio> const int Max = 10000; int n,a[Max],p[Max]; #include <algorithm> using namespace std; int main() { scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&p[i]); sort(p,p+n); do { for(int i = 0; i < n; i++) printf("%d",p[i]); printf("\n"); }while(next_permutation(p,p+n)); return 0; }