zoukankan      html  css  js  c++  java
  • [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;
    		}
    	}
    }
    
  • 相关阅读:
    Delphi 与 DirectX 之 DelphiX(28): TDIB.Emboss;
    Delphi 与 DirectX 之 DelphiX(29): TDIB.AddMonoNoise();
    Delphi 与 DirectX 之 DelphiX(33): TDIB.SmoothRotateWrap();
    如何用w.bloggar从桌面发表文章
    可以插入图片了
    在首页可以查看阅读次数了
    .Text的MainFeed.aspx生成RSS的问题
    首页文章显示说明
    欢迎光临博客园
    如果想学习.Net Remoting,请看看MSDN上的一篇文章
  • 原文地址:https://www.cnblogs.com/by-sknight/p/11026392.html
Copyright © 2011-2022 走看看