【题解】 UOJ #2. 【NOI2014】起床困难综合症

传送门


不是很简单?
考虑一下这个数的二进制位是什么,要么是1,要么是0.
然后怎么做?
因为一开始可以选0~m的数,那么二进制为中全是0的肯定是可以选的。
接着考虑全是1的怎么选?
如果全都是1的而且比m要小,那么显然就可以选。
注意从大到小贪心的选(二进制为当前位往后面的和是一定不可能超过当前位的)。

#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
int a=2147483647,b=0,n,m,ans;
char s[5];
int main(){
	int n,m;scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int t;
		scanf("%s%d",s,&t);
		if(s[0]=='A'){a=a&t;b=b&t;}
		if(s[0]=='O'){a=a|t;b=b|t;}
		if(s[0]=='X'){a=a^t;b=b^t;}
	}
	for(int i=30;i>=0;i--)
		if(b&(1<<i))ans+=1<<i;
		else if(m>=(1<<i) && a&(1<<i))ans+=1<<i,m-=(1<<i);
	printf("%d\n",ans);
	return 0;
}
posted @ 2018-11-07 17:40  cjgjh  阅读(176)  评论(0编辑  收藏  举报