题解 | #起床困难综合症#
起床困难综合症
https://ac.nowcoder.com/acm/problem/17857
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int main()
{
unsigned int n,m;
cin>>n>>m;
int s0=0,s1=-1;
for(int i=0;i<n;i++)
{
string op;
int t;
cin>>op>>t;
if(op[0]=='O')
{
s0 = (s0|t);
s1 = (s1|t);
}
if(op[0]=='A')
{
s0 = (s0&t);
s1 = (s1&t);
}
if(op[0]=='X')
{
s0 = (s0^t);
s1 = (s1^t);
}
}
int ans=0;
for(int i=31,chushi=0;i>=0;i--)
{
if(((s0>>i)&1)==1)
{
ans+=(1<<i);
continue;
}
if((((s1>>i)&1)==1)&&((chushi+(1<<i))<=m))
{
chushi+=(1<<i);
ans+=(1<<i);
}
}
cout<<ans<<endl;
return 0;
}
重点:
- 按位思考,各位隔离思考。每位只有0/1两种情况,因此可以用s0=0(每位全0),s1=-1(每位全1)来走一遍运算得到结果。然后对两个结果的各位进行分析。
- 分析思路:要使伤害最大化,则使高位到低位尽量为1(贪心),同时要注意初始攻击力不能超过m(这是本题唯一限制)
- 我们要考虑两种情况:一是s0的某位变1(0->1),此时是最方便最理想的情况,直接将最终攻击的该位置1(加上1的左移);二是s1的某位保持1(1->1),此时要考虑m的限制,如果符合限制(初始攻击该位置1后不超过m),则将最终攻击该位置1,同时将初始攻击该位置1 4.对于0<数据<=1e9,尽量使用unsigned int。如本题m若为int则按位操作时i应从30开始,否则不能AC,而m直接设置成unsigned int时较为方便。