/*
生成一个集合的子集合的方法
首先知道一共有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