子集合的构造

/*
生成一个集合的子集合的方法

首先知道一共有2^n的子集合
一个集合等于一个已经构造好的左边集合和一个等待构造的右边集合构成


*/



#include<iostream>
using namespace std;
const int maxn = 1e5;
int D[maxn];
int S[maxn];
int n;
void subset(int cur,int loc)//左边集合用到了[0,cur)的元素
{
    //先将已经构造好的左边集合打印出来,此时右边集合为空集
    if (!loc) cout << "!" << endl;
    else
    {
        for (int i = 0; i<loc; i++)
        {
            if (i) cout << " ";
            cout << S[i];
        }
        cout << endl;
    }
    //保留已经构造好的左边集合,构造右边集合
    for (int i = cur; i<n; i++)
    {
        S[loc] = D[i];
        subset(i + 1,loc+1);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 0; i<n; i++)
    {
        cin >> D[i];
    }
    subset(0,0);
    return 0;
}

第二种方法:

#include<iostream>
const int maxn = 1e5 + 7;
using namespace std;
int D[maxn];
bool B[maxn];
int n;
void fun(int cur)
{
    if (cur == n)
    {
        for (int i = 0; i < n; i++)
        {
            if (B[i])
            {
                cout << " " << D[i];
            }
        }
        cout << endl;
    }
    else
    {
        B[cur] = 0;
        fun(cur + 1);
        B[cur] = 1;
        fun(cur + 1);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> D[i];
    }
    fun(0);
    return 0;
}

方法三:

//最好的方法,因为比较快,代码简单,同时|,&,^对应集合中的并,交,对称差
#include<iostream>
using namespace std;
const int maxn = 1e5 + 7;
int D[maxn];
int n;

inline void sub_print(int x)
{
    for (int i = 0; i < n; i++)
    {
        if ((x&(1 << i))) cout << D[i] << " ";
    }
    cout << endl;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> D[i];
    }
    for (int i = 0; i < (1 << n) - 1; i++)
    {
        sub_print(i);
    }
    return 0;
}


剩下993

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值