[Aizu] ITP2_11_A~D: 子集的枚举系列
Posted by-sknight
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Aizu] ITP2_11_A~D: 子集的枚举系列相关的知识,希望对你有一定的参考价值。
前言
ITP系列之使用位集枚举, 具体内容参见bitset
PS: 感觉第三个与第四个拓展之后实用性较强
题目链接
ITP2_11_A: Enumeration of Subsets I
ITP2_11_B: Enumeration of Subsets II
ITP2_11_C: Enumeration of Subsets III
ITP2_11_D: Enumeration of Combinations
求解
第一题
分析
要求n个数的组合, 组合内元素数量不限, 创建一个位集, 从0一直增加到小于2的n次方即可, 每次都输出
代码
#include <bits/stdc++.h>
using namespace std;
void print(bitset<20> b)
for (int i = 0; i < 20; i++)
if (b.test(i))
cout << " " << i;
int main(void)
ios::sync_with_stdio(false);
cin.tie(0);
bitset<20> b1, b2;
int n;
cin >> n;
int max = 1 << n;
for (int i = 0; i < max; i++)
cout << i << ":";
b2 = i;
print(b2);
cout << endl;
第二题
分析
求n个数的组合, 组合满足T集合是它的子集, 如T = 1, 2, 那么形如1, 2, 3, 1, 2, 5等这种都可以, 2, 3, 5 这种不可以
代码
#include <bits/stdc++.h>
using namespace std;
void print(bitset<20> b)
for (int i = 0; i < 20; i++)
if (b.test(i))
cout << " " << i;
int main(void)
ios::sync_with_stdio(false);
cin.tie(0);
bitset<20> b1, b2;
int n; cin >> n;
int max = 1 << n;
int k; cin >> k;
for (int i = 0; i < k; i++)
int x; cin >> x;
b1.set(x);
for (int i = 0; i < max; i++)
b2 = i;
if ((b2 | b1) == b2)
cout << i << ":";
print(b2);
cout << endl;
第三题
分析
给定一个集合T, 是S集合的子集, S集合是一个简单的集合 0 ~ n-1, 而T集合则是其中特定的元素的集合, 要求输出所有集合T的元素的全组合
通过用一个位集一点点增加上去, 会发生超时.
如果把T看作一个数组, 那么就可以使用一个长度为T的长度的位集, 来依次增加, 得到的一个位集作为T中元素的下标, 然后输出即可
代码
#include <bits/stdc++.h>
using namespace std;
void print(bitset<32> b)
for (int i = 0; i < 32; i++)
if (b.test(i))
cout << " " << i;
int main(void)
ios::sync_with_stdio(false);
cin.tie(0);
bitset<32> b1, b2;
vector<int> vec;
int n; cin >> n;
int k; cin >> k;
int max = 1 << k;
for (int i = 0; i < k; i++)
int x; cin >> x;
vec.push_back(x);
for (int i = 0; i < max; i++)
b1 = i;
b2.reset();
for (int j = 0; j < vec.size(); j++)
if (b1.test(j) == 1)
b2.set(vec[j]);
cout << b2.to_ulong() << ":";
print(b2);
cout << endl;
第四题
分析
要求的是从n个数中取出k个数的全组合, n个数分别为 0 ~ n-1, 创建一个位集, 然后从值从0一直增加, 如果1的数量恰好为k个, 输出即可
代码
#include <bits/stdc++.h>
using namespace std;
int main(void)
ios::sync_with_stdio(false);
cin.tie(0);
int n, k; cin >> n >> k;
bitset<18> b;
int max = 1 << n;
for (int i = 0; i < max; i++)
b = i;
if (b.count() == k)
cout << i << ":";
for (int j = 0; j < n; j++)
if (b.test(j))
cout << " " << j;
cout << endl;
以上是关于[Aizu] ITP2_11_A~D: 子集的枚举系列的主要内容,如果未能解决你的问题,请参考以下文章