O(n!) 求长度为n的序列的全排列:
①递归实现:(参考--https://blog.csdn.net/hero_boke/article/details/58637535)
#include<cstdio> #include<algorithm> using namespace std; int n,a[10]; void get_permutation(int layer){ if(layer==n) { for(int i=1;i<=n;i++) printf("%d",a[i]); printf(" "); return; } for(int i=layer;i<=n;i++){ swap(a[i],a[layer]); get_permutation(layer+1); swap(a[i],a[layer]); } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); get_permutation(1); }
②STL--next_permutation算法:
next_permutation(“序列范围”)将原序列中所给范围的元素进行全排,(该范围内)原序列变为比其字典序大的下一个序列,若没有下一个序列返回false,否则返回true;
如{1,2,3}的下一个序列为{1,3,2};而{3,2,1}没有下一个序列;
与之类似的有prev_permutation算法,其意义为获得原序列的“上一个”序列;
#include<cstdio> #include<algorithm> using namespace std; int n,a[10]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); do{ for(int i=1;i<=n;i++) printf("%d",a[i]); printf(" "); }while(next_permutation(a+1,a+1+n)); }
例:hdu1027--http://acm.hdu.edu.cn/showproblem.php?pid=1027
思路:可以康托展开,或直接用next_permutation
AC代码:
#include <iostream> #include<cstdio> #include<algorithm> using namespace std; int main() { int n,m,a[1010]; while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) a[i]=i; int cnt=0; do{ cnt++; if(cnt==m) {for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n?' ':' ');break;} }while(next_permutation(a+1,a+1+n)); } return 0; }