子集生成——增量构造法
//此处简单介绍增量构造法 非此题目最优解法
子集
Time Limit: 400/200MS (Java/Others)
Memory Limit: 32768/32768K (Java/Others)
Description
n个整数构成的集合,求它的所有子集。集合元素不妨设为: 1,2,3,... , n-1, n
Input
有多个测试用例,每个测试用例是一个整数n ( 1 ≤ n ≤ 15 )
Output
对每个测试用例,输出它的所有子集,"从小到大"输出这些子集。
"从小到大"的意思:先输出元素个数较少的集合,然后才输出元素个数较多的集合。
当有若干个子集的元素的个数一样时,先输出拥有较小元素的集合,然后才输出拥有较大元素的集合。
例:{ 1, 2 } < { 1, 3 } 。
输出一个子集时,首先输出该子集的元素个数,接着是一个空格,接着从小到大输出这个子集的每个元素,元素之间用一个空格分隔。
每个测试用例之间输出一个空行。温馨提示:行末没有空格。
Sample Input
3
1
Sample Output
0
1 1
1 2
1 3
2 1 2
2 1 3
2 2 3
3 1 2 3
0
1 1
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
using namespace std;
int B[100];
int A[100];
int C[100];
int P[20][10000][20];
void print_subset(int n,int *B,int cur)
{
if(cur!=0)
{
for(int i=0; i<cur; i++)
{
P[cur][C[cur]][i]=A[B[i]];//一维为长度,二维为此长度子集的数量,三维为这个子集是啥
}
C[cur]++;
}
int s=cur?B[cur-1]+1 : 0;//向后一位
for(int i= s; i<n; i++)
{
B[cur]=i;
print_subset(n,B,cur+1);
}
}
int main()
{
int n;
//freopen("sdf.txt","w",stdout);
while(~scanf("%d",&n))
{
memset(C,0,sizeof(C));
printf("0\n");
for(int i=0; i<n; i++)
A[i]=i+1;
print_subset(n,B,0);
for(int i=1; i<=n; i++)
{
for(int j=0; j<C[i]; j++)
{
printf("%d ",i);
for(int k=0; k<i; k++)
{
if(k!=i-1)
printf("%d ",P[i][j][k]);
else
printf("%d",P[i][j][k]);
}
printf("\n");
}
}
printf("\n");
}
return 0;
}
基本
只能用于0~n的数据,但可像上述题目那样作为数组下标进行处理
void print_subset(int n, int *A, int cur)
{
for(int i=0;i<cur;i++)
printf("%d",A[i]);//输出子集
printf("\n");
int s=cur?A[cur-1]+1:0;//1 2的话后面若再增就是2+1
for(int i=s;i<n;i++)
{
A[cur]=i;
print_subset(n,A,cur+1);
}
}