每日一题——起床困难综合症
题目
题解
如果将所有伤害点数一一枚举的话,时间复杂度会来到O(nm),对此肯定是满足不了题目要求的,经过分析不难发现,位运算操作只与当前位有关,这样我们可以枚举每一位,再在其中选其优,这样子时间复杂度就来到了O(nlogm),,由于伤害要尽可能大,所以我们要从高位开始往下,接下来会出现三种情况:
I该位为1经过操作后的值大于该位为0经过操作后的值
II该位为1经过操作后的值大于该位为0经过操作后的值
III该位为1经过操作后的值大于该位为0经过操作后的值
对于第I种情况而言,如果不超出最大伤害我们就可以选择该位为1
其他情况来说能选0则选0,会对后面的选择减少超出m的可能。
切记最后题目让我们求的是什么,别把攻击力值写上去哦。
参考代码
#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m, num[N];
char op[N][4];
int cul(int bit, int x){
for(int i = 0; i < n; i ++){
int t = (num[i] >> bit) & 1;
if(op[i][0] == 'A') x &= t;
else if(op[i][0] == 'O') x|= t;
else x ^= t;
}
return x;
}
int main(){
cin >> n >> m;
for(int i = 0; i < n; i ++) cin >> op[i] >> num[i];
int hit = 0, res = 0;
for(int i = 30; ~i; i --){
int t1 = cul(i, 1);
int t2 = cul(i, 0);
if((1 << i) + hit <= m && t1 > t2) hit += 1 << i, res += t1 << i;
else res += t2 << i;
}
cout << res << endl;
return 0;
}

浙公网安备 33010602011771号