枚举排列
来源:互联网 发布:金融行业数据分析师 编辑:程序博客网 时间:2024/06/10 07:27
生成1~n的排列:
输入整数n,按字典序从小到大的顺序输出前n个数的所有排列。生成1~n的排列可以通过递归思想解决!
#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>using namespace std;const int Max = 100000 + 10;int mem[Max];void solve(int n, int *a, int num){ if(num == n)///递归边界 { for(int i = 0; i < n - 1; i++) printf("%d ",a[i]); printf("%d\n",a[n-1]); } else { for(int i = 1; i <= n; i++)///在a[num]中遍历一遍所有数 { int ok = 0; for(int j = 0; j < num; j++) { if(a[j] == i)///判断a[0]~a[num-1]是否出现过该数字,出现标记为1 ok = 1; } if(!ok) { a[num] = i; solve(n,a,num+1); } } } return;}int main(){ int n; while (~scanf("%d",&n)) { solve(n,mem,0); } return 0;}
输入数组q,并按字典序从小到大的顺序输出数组a各元素的所有全排列。生成可重集的排列同样是通过递归思想解想,需注意排列没有遗漏和重复!
#include <bits/stdc++.h>using namespace std;const int Max = 100000 + 10;int mem[Max], q[Max];void solve(int n, int *p, int *a, int num){ if(num == n)///递归边界 { for(int i = 0; i < n - 1; i++) printf("%d ",a[i]); printf("%d\n",a[n-1]); } else { for(int i = 0; i < n; i++)///在a[num]中遍历一遍p数组中所有的数 { int bj1 = 0, bj2 = 0; if(!i || p[i] != p[i-1])///避免重复 { for(int j = 0; j < num; j++) if(a[j] == p[i]) bj1++;///统计a[0]~a[num-1]中p[i]的出现次数bj1; for(int j = 0; j < n; j++) if(p[i] == p[j]) bj2++;///统计p数组中p[i]的出现次数bj2; if(bj1 < bj2)///避免遗漏 { a[num] = p[i]; solve(n,p,a,num+1); } } } } return;}int main(){ int n; while (~scanf("%d",&n)) { for(int i = 0; i < n; i++) scanf("%d",&q[i]); sort(q,q+n); solve(n,q,mem,0); } return 0;}
除了上述的用递归来解决两个问题外,还可以用STL自带函数next_permutation来解决生成1 ~ n的排列、生成可重集的排列两个问题!next_permutation(mem,mem+n)表示对mem数组的mem[0] ~ mem[n]之间的数字按字典序进行排列!
#include <algorithm>#include <iostream>#include <string.h>#include <stdio.h>#include <math.h>using namespace std;const int Max = 100000 + 10;int n, mem[Max];void solve_int()///int 类型的 next_permutation 使用{ for(int i = 0; i < n; i++) scanf("%d",&mem[i]); sort(mem,mem+n); do { for(int i = 0; i < n - 1; i++) printf("%d ",mem[i]); printf("%d\n",mem[n-1]); }while(next_permutation(mem,mem+n));}void solve_char()///char 类型的 next_permutation 使用{ int len; char ch[Max]; scanf("%s",ch); len = strlen(ch); sort(ch,ch+len); do { printf("%s\n",ch); }while(next_permutation(ch,ch+len));}void solve_string()///string 类型的 next_permutation 使用{ string str; while(cin >> str && str != "*") { sort(str.begin(),str.end()); do { cout << str << endl; } while(next_permutation(str.begin(),str.end())); }}bool cmp(char a, char b)///自定义排序顺序,'A' < 'a' < 'B' < 'b' ... < 'Z' < 'z'{ if(tolower(a) == tolower(b)) return a < b; else return tolower(a) < tolower(b);}void solve_mem()///自定义排序方法后 next_permutation 的使用{ int len; char ch[Max]; scanf("%s",ch); len = strlen(ch); sort(ch,ch+len,cmp); do { printf("%s\n",ch); }while(next_permutation(ch,ch+len,cmp));}int main (){ scanf("%d", &n); solve_int(); solve_char(); solve_string(); solve_mem(); return 0;}
0 0
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 枚举排列
- 关于排列枚举算法
- 递归枚举全排列
- 枚举全排列
- 枚举全排列
- hdu 1059 Dividing(完全背包)
- LNOI2013最小距离之和题解
- c++前置声明
- 手机安全卫士07
- 文章标题
- 枚举排列
- 工厂方法模式(创建型)
- vector的成员函数解析
- 文章标题
- eclipse 背景颜色修改
- Android view动画问题
- Android studio 解决libpng warning: iCCP: Not recognizing known sRGB profile that has been edited
- Android 不规则封闭区域填充 手指秒变油漆桶
- CocoaPods Guide