输入n个数,求这n个数构成的集合的所有子集,不允许输出重复的项
输入
3
1 1 3
输出
1
1 1
1 1 3
1 3
3
代码:
#include<cstdio> #include<cstring> using namespace std; const int maxn = 100; int rcd[maxn],num[maxn],vis[maxn]; int n,m; int read_input() { if(scanf("%d",&n)==EOF) return 0; m=0; memset(vis,0,sizeof(vis)); int i,j; for( i=0;i<n;i++){ int val; scanf("%d",&val); for( j=0;j<m;j++) if(num[j]==val){ vis[j]++; break; } if(j==m){ num[j]=val; vis[m++]++; } } return 1; } void unrepeat(int l,int p){ for(int i=0;i<l;i++){ printf("%d",rcd[i]); if(i<l-1) printf(" "); } printf(" "); for(int i=p;i<m;i++) if(vis[i]>0){ vis[i]--; rcd[l]=num[i]; unrepeat(l+1,i); vis[i]++; } } int main(){ while(read_input()) unrepeat(0,0); return 0; }
引用别人说的话:“搜索问题中很多本质上是排列组合问题,只不过加上了某些剪枝和限制条件,解这类题的基本算法框架常常是类循环排列,劝排列,一般组合或者全组合,而不重复排列和不重复组合则是两种非常有效的剪枝技巧”