子集生成之增量构造法

子集生成——增量构造法  

//此处简单介绍增量构造法 非此题目最优解法


子集

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
#include
#include
#include
#include
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        {
            P[cur][C[cur]][i]=A[B[i]];//一维为长度,二维为此长度子集的数量,三维为这个子集是啥
        }
        C[cur]++;
    }
    int s=cur?B[cur-1]+1 : 0;//向后一位
    for(int i= s; 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            A[i]=i+1;

        print_subset(n,B,0);

        for(int i=1; i<=n; i++)
        {
            for(int j=0; j            {
                printf("%d ",i);
                for(int k=0; 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        printf("%d",A[i]);//输出子集
    printf("\n");
    int s=cur?A[cur-1]+1:0;//1 2的话后面若再增就是2+1
    for(int i=s;i    {
        A[cur]=i;
        print_subset(n,A,cur+1);
    }
}


你可能感兴趣的:(算法_acm)