二进制枚举集合

#include<iostream>
#include<cstdlib>
using namespace std;
int a[10]={0,1,2,3,4,5,6,7,8,9};
const int n=10;
int main()
{
    /*
        当n=3时,那么有集合0,1,2,01,02,12,012七种情况
        i=1时 001只选择最后一位
        i=2时 010只选择第二位
        i=3时 011 选择后面两位

        i=7时 111全选

        因此我们只要通过i&1来判断是不是该选
        比如i=7时,我们首先让s=1 那么111&001选择了第三位
        再让s左移一位 即111&010选择了第二位
        再让s左移一位 即111&100选择了第一位
        循环结束,选择完毕

    */
    int i;
    for(i=1;i<(1<<n);i++)//子集的个数
    {
       for(int j=0,s=1;j<n;j++)//子集的内容
        {
            int x = i&s;
            if(x)
            cout<<a[j]<<‘ ‘;
            s=(s<<1);
        }
        cout<<endl;
    }
}
时间: 2024-10-13 12:51:05

二进制枚举集合的相关文章

1151 - Buy or Build(二进制枚举子集 + 并查集)

这题LRJ书上翻译的有问题,书上说两点之间的cost是两点的欧几里得距离,而题目要求两点的距离是两点欧几里得距离的平方. 其余就没什么好说的了,裸的并查集,需要注意的就是二进制枚举子集的问题. 二进制枚举子集: for(int i = 0 ; i < (1 << s) ; i++){ /*s是集合元素的个数*/ for(int j = 0 ; j < s ; j++){ if(!(s >> j) & 1) continue; else{ } } } 140548

关于二进制枚举

算是彻底搞懂二进制枚举吧. 首先一个集合的子集有2^n个,所以我们枚举的个数有(1<<n)个: 所以 for(int i=0; i<(1<<n); i++) 我们知道二进制枚举的过程如下: 每个位置值为1则保留,不为1则舍弃 : 设s=13(二进制为1101)那么我们保留0 2 3位置上的数值: 那么我们如何找到每个位置上的数值呢? 我们遍历的是二进制的十进制表示(比如13),我们当然可以转化为二进制在枚举每一位,但是,这很麻烦: 一个很巧妙的方式就是利用位运算: 1<

子集的生成—二进制枚举

有这样的一个问题: 给定一个集合,让你输出所有的子集. 这时候二进制就派上了用场~ 我们用0,1来表示当前位是否被保留,值为1则保留,为0则舍弃 ,如下图所示: 那么对于一个有n个数的集合来讲,每一位有取和不取两种状态,一共就有2n种状态,我们可以从0一直枚举到2n来表示所有子集的状态. 但是现在问题又来了,对与我们枚举的数,你怎么知道哪一位是0,哪一位是1? 这个时候就要用到位运算的知识了,对于一个数S(子集的状态)我们拿它和0~n每一位i进行S&(1<<i)这样的运算就能得到对于的

UVa 818 切断圆环链(dfs+二进制枚举)

https://vjudge.net/problem/UVA-818 题意:有n个圆环,其中有一些已经扣在了一起.现在需要打开尽量少的圆环,使得所有圆环可以组成一条链,例如,有5个圆环,1-2,2-3,4-5,则需要打开一个圆环,如圆环4,然   后用它穿过圆环3和圆环5后再次闭合4,就可以形成一条链:1-2-3-4-5. 思路:从n个圆环中任意选择圆环,这就是枚举子集.所以这道题目可以用二进制枚举来做. 那么如何判断当前打开圆环是可行的呢?在去除打开的圆环后需要判断: ①:每个圆环的分支数都必

UVa818 Cutting Chains (二进制枚举)

链接:http://vjudge.net/problem/35523 分析:links记录初始圆环链的情况,然后二进制枚举编号为0~n-1的圆环哪个被打开了,一个圆环最多一个前驱和一个后继,所以judge判断如果有一个未打开的圆环同时和2个以上的未打开圆环相连就一定不能形成链,剪去.circle判断剩下的未打开圆环是否形成环,以及若未成环那么有多少条单链links_num,注意最后成链不用按顺序比如1->2->3...这样.然后判断一下打开的圆环数够不够把links_num条单链扣成一条链,若

第十九章、枚举集合

foreach极大地简化了需要编写的代码,但它只能在特定情况下使用——只能使用foreach遍历可枚举集合. 什么是可枚举集合?简单地说就是实现了System.Collections.IEnumerable接口的集合. IEnumerable接口包含一个名为GetEnumerator的方法: IEnumerator GetEnumerator(); GetEnumerator方法应该返回实现了System.Collections.IEnumerable接口的枚举器对象,枚举器对象用于遍历(枚举)

POJ 2436 二进制枚举+位运算

题意:给出n头牛的得病的种类情况,一共有m种病,要求找出最多有K种病的牛的数目: 思路:二进制枚举(得病处为1,否则为0,比如得了2 1两种病,代号就是011(十进制就是3)),首先枚举出1的个数等于k的二进制数,然后跟所有的牛的代号一一比较,符合的           +1,找出其中和最大的:就是转换2进制麻烦,用位运算就好实现了,但是位运算不是很明白含义,明白了再补充: 知识点: 3 & 2 = 2,相同为1,不同为0, 011 & 010 = 010:(怎么利用的这个特点不明白):

UvaLive 6661 Equal Sum Sets 二进制枚举/DP

链接:http://vjudge.net/problem/viewProblem.action?id=49406 题意:根据给出的n,k,s求出n个数每个数都不大于k,和为s的序列(n个数每个都不同)的总情况数. 思路: 1.二进制枚举枚举出所有可能排列,并求和若和为s,则符合,否则不符合. 代码: #include<iostream> #include<set> #include<map> #include<queue> #include<cstri

wikioi 2144 分步二进制枚举+map记录

题目描述 Description 有n个砝码,现在要称一个质量为m的物体,请问最少需要挑出几个砝码来称? 注意一个砝码最多只能挑一次 输入描述 Input Description 第一行两个整数n和m,接下来n行每行一个整数表示每个砝码的重量. 输出描述 Output Description 输出选择的砝码的总数k,你的程序必须使得k尽量的小. 样例输入 Sample Input 3 10 5 9 1 样例输出 Sample Output 2 数据范围及提示 Data Size & Hint 1