[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;
}
}
}
标签:11,ITP2,位集,int,cin,++,b1,b2,Aizu 来源: https://www.cnblogs.com/by-sknight/p/11026392.html