题目链接
AcWing 998.
题意:最初攻击力不知道,给定m次位运算操作,计算经过m次位运算操作后的最大值。
思路:在代码顶部
混合位运算不具有分配律,交换律,结合律
// 存在多个不同的位运算符号时,不具有结合律,因此不能先算后面
/*
x & 5 | 6 ^ 7 != x & (5 | 6 ^ 7)
x = 2时,左边为1,右边为0
*/
// 思路:按位去判断,从高到低枚举每一位的两种情况.
// 2^30 > 1e9
#include <bits/stdc++.h>
using namespace std;
typedef pair<string,int> PSI;
PSI a[100010];
int n,m,t;
bool calc(int bit,int now){
for(int i=1;i<=n;i++){
int x = ((a[i].second >> bit) & 1);
if(a[i].first=="AND"){
now &= x;
}else if(a[i].first=="OR"){
now |= x;
}else{
now ^= x;
}
}
return (now==1);
}
int main()
{
std::ios::sync_with_stdio(false);std::cin.tie(nullptr);
// cout << (1<<30) << endl; 1073741824
string op;
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> op >> t;
a[i] = make_pair(op,t);
}
int initatack = 0; //初始攻击力.
for(int i=29;i>=0;i--){
int bit = i;
if(initatack + (1<<bit) > m || calc(bit,0)) continue;
if(calc(bit,1)){
initatack += (1 << bit);
}
}
int ans = initatack;
for(int i=1;i<=n;i++){
int x = a[i].second;
if(a[i].first=="AND"){
ans &= x;
}else if(a[i].first=="OR"){
ans |= x;
}else{
ans ^= x;
}
}
cout << ans << endl;
return 0;
}