一、符号(将两数作为二进制数,每一位逐一运算):
1、& (and) 与运算符 (两位都为1时才为1)。
2、| (or) 或运算符 (两位任意一位为1时才为1)。
3、^ (xor) 异或运算符 (两位相同时才为1)。
二、编码:
1、原码:计算机里存的是二进制数,第一位是0表示正数,是1表示负数。
2、反码:正数的反码与原码相同,负数的反码是对原码按位取反。
3、补码:正数的补码与原码相同,负数的补码为反码加1。
三、取反(对一个数num进行位运算,即单目运算):
取反符(~)
把num的二进制补码中的0和1全部取反。
有符号整数的符号位在~运算中同样会取反。
四、左移和右移:
1、num<<i 表示将num的二进制表示向左移动 位所得的值。
2、num<<i 表示将num的二进制表示向右移动 位所得的值。
3、移位运算中如果出现如下情况,则系统判定为为未定义:
右操作数(即移位数)为负值;
右操作数大于等于左操作数的位数;
4、真题演练:(oiClass2021 比萨)
题目描述:
NH的最大比萨店为即将来临的节日准备了 T 种不同加味的原料,但考虑到NH人的口味和其它一些因素,原料的使用有 N 种限制。
T种不同原料的编号为1..T。一个限制如"5 3"即表示5号和3号加味原料不能同时使用。如此,此时使用三种原料3,5,6的比萨是不允许的。
现在请你帮忙计算在上面条件下,最多可以制作多少不同的比萨(包括不添加任何加味原料的)。
数据范围: 1≦T≦20 1≦N≦52
输入:
第一行:两个整数:T 和 N。
下面有N行:每行表示一种限制。每行的第一个整数 Z(1≦Z≦ T)表示这行后面有Z个表示原料编号的整数,这些原料不能同时出现在一个比萨中
输出:
只一行,一个整数表示在上面的限制下最多可以制成多少种不同比萨。
输入样例:
6 5
1 1
2 4 2
3 3 2 6
1 5
3 3 4 6
输出样例:
10
提示:
答案说明:
无加料;2;
2和3;2和6;
3;3和4;
3和6;4;
4和6;6。
思路:
由于T很小,只有20,所以我们可以枚举出每一种方案。将每一种方案i用二进制表示,如十进制的11就表示二进制的1011,即选1、2、4种调料。
代码:
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <cstring>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <list>
#include <map>
#define int long long
using namespace std;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
int t,n,z,k,ans=0,a[60];
signed main(){
cin >>t>>n;
for(int i=1;i<=n;i++){
cin >>z;
for(int j=1;j<=z;j++){
cin >>k;
a[i]=a[i]|(1<<(k-1));
}
}
int len=1<<t;
for(int i=0;i<len;i++){
bool p=false;
for(int j=1;j<=n;j++){
if((i&a[j])==a[j]){
p=true;break;
}
}
if(p==false)ans++;
}
cout <<ans;
}