bitset妙用

前置知识:bitset其实是用unsigned来实现的
bitset的基本用法:

  • 初始化:
bitset<n> b(u);	          //b是unsigned long型u的一个副本
bitset<n> b(s);	          //b是string对象s中含有的位串的副本
bitset<n> b(s, pos, n);	  //b是s中从位置pos开始的n个位的副本 
bitset<32> bitvec; //32位,全为0。
string strval("1100");
bitset<32> bitvec4(strval); //注意:用string初始化bitset是从右向左,也就是将其当成一个位数来看,每个位置就是一位,而不是它现在表示的数字,这里第0,1位为0;2,3位为1
  • 相应API
b.any(); //存在为1的位吗
b.none(); //不存在为1的位吗
b.count(); //返回为1的位数
b.size(); //b中二进制的位数
b[pos]; //访问b的第pos位的二进制位
b.set(); //把b中所有位置为1
b.reset(); //把b中所有位置为0
b.set(pos); //把b中第pos位置为1
b.reset(pos); //把b中第pos位置为0
b.flip(); //把b中所有位取反
b.flip(pos); //把b中第pos位的取反
b.to_ulong(); //返回转化得到的unsigned long 
  • 常用操作
bitset<32> bitvec2(0xffff); // bits 0 ... 15 are set to 1; 16 ... 31 are 0
cout << "bitvec2: " << bitvec2 << endl;  //会输出二进制表示的string
bitvec2: 00000000000000001111111111111111 
&nbsp;
可以对整个bitset进行移位,异或等位运算(这里直接将其看成unsigned long类型的数)
b |= num;
b >>= num;
b <<= num;
b ^= num;
b &= num; //这里的num被认为是unsigned long类型,所以注意负数,而且这也意味这num可以是bitset类型

 
示例:
Leecode.1981

class Solution {
public:
    int minimizeTheDifference(vector<vector<int>>& mat, int target) {
        bitset<5000> c, b;
        b.set(0);
        for(vector<int>& m: mat)
        {
            for(int num: m)
                c |= (b << num);
            b = c;
            c.reset();
        }
        for(int i = 0; i < 5000; ++i)
        {
            if((target-i >= 0 && b[target-i]) || (target+i < 5000 && b[target+i]))
                return i;
        }
        return target;
    }
};

思想:每次保存到当前行可以得到的数,枚举到最后相当于完全dfs了一遍,但是这种方式更加简洁,更加省时间,以后遇到枚举型题目(规模小,规律不容易探寻),可以考虑用bitset解决

posted @ 2023-01-22 18:40  兮何其  阅读(47)  评论(0)    收藏  举报