不重复排列的生成
来源:互联网 发布:mac os dmg 下载地址 编辑:程序博客网 时间:2024/05/23 07:25
全排列的话比较好打。
可,当一个集合中有许多重复的元素,如{2,2,2,2,2} 如何生成不重复的排列?
易知答案只有一个。
生成不重复排列,这很实用。
思想:把重复的数字不在看做多个元素,而是看做一个元素的多个个数。
然后递归生成时,添加在答案里的是次数的减少。
正确性:如果按照以上思路,那么可以知道,每个因为我们把重复的元素当做一个元素的多个来处理,那么当一个有重复的元素递归回来时,那么这个整个重复的元素就已经完成了它的赋值给ans,例如:执行2 1 1 的时候 会再递归回2 1 0的位置,但此时就不会在添加一遍 1, 而如果是全排列的话, 2 个 1 是不同的元素,后一个1 可能和 前一个交换位置,还是2 1 1。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int MAXN = 100 + 1;int n, m;int num[MAXN], ans[MAXN];int vis[MAXN];void init(){ memset(num,0,sizeof(num)); memset(ans,0,sizeof(ans)); memset(vis,0,sizeof(vis)); m = 0;}inline void print(){ for(int i = 1; i <= n; i ++) printf("%d ", ans[i]); printf("\n");}void dfs(int x){ if(x > n) { print(); return; } else{ for(int i = 1; i <= m; i ++) { if(vis[i] > 0) { vis[i] --; ans[x] = num[i]; printf("ans[%d] = num[%d];\n", x, i); dfs(x+1); vis[i] ++; } } }}int main(){ while(cin >> n) { init(); for(int i = 1; i <= n; i ++) { int t; scanf("%d",&t); vis[i] ++; bool re = false; for(int j = 1; j <= m; j ++) if(t == num[j]) { vis[j] ++; re = true; break; } if(!re) { num[++m] = t; } } dfs(1); return 0; } return 0;}/*31 1 21 1 21 2 12 1 1*/
1 0
- 不重复排列的生成
- 非重复组合排列(含重复数字时,生成不重复组合排列)
- 求不重复数据的全排列
- 不重复数列的全排列
- LRJ生成可重复的排列
- 非重复生成全子集组合排列(含重复数字时,生成不重复全子集组合排列)
- 全排列不重复
- 生成不重复的随机数
- 生成不重复的随机数
- 生成不重复的随机数
- 生成不重复的随机数
- 生成不重复的数字!
- 生成不重复的随机数
- 生成不重复的随机数
- 生成不重复的订单号
- 生成不重复的随机数
- 生成不重复的随机数
- 如何得到有重复元素的不重复全排列
- BZOJ 4300: 绝世好题【DP
- hadoop整理笔记
- 比较nice的文章记录mark
- 打印100—200之间的素数
- 【个人】2016年-2017 必看书单
- 不重复排列的生成
- TP框架的目录结构总结
- javac 与 Maven compiler Plugin
- 指针和引用的联系与区别
- Linux进程实践(2) --僵尸进程与文件共享
- jquery复选的添加和移除
- Node Addon开发(第一部分):运行Github上的Node Addon例子
- raptor程序:我的第二个分段函数
- POJ 2955Brackets(区间dp)