【题解】洛谷P2114 [NOI2014]起床困难综合症

本文详细解析洛谷P2114[NOI2014]起床困难综合症的算法题解。通过贪心策略,从高位到低位确定原数的每一位,以最大化操作后的数值,同时考虑到原数的大小限制。

题目

洛谷P2114 [NOI2014]起床困难综合症

题解

题意简化为:在0~m之间找一个数,使得这个数在一系列操作后最大。

由于原数有大小限制,又要使得到的数尽量大,为了充分地利用限制,就需要按位从高到低贪心,确定原数是选0还是选1。如果可以使得到的数为1,则尽量选,同时要考虑原数限制,还要使原数尽量小。

需要记录每一位为0或1时,在经过操作后会变成什么。只要用一个全0数和一个全1数整体操作即可,最后一位位取出来。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,a0,a1,t,ans,st;
char ch[5];
inline void get_ans()
{
	for(int i=30;i>=1;i--)	//st是原数 
	{
		int cur=1<<(i-1);	//cur只有第i位为1 
		if(a0&cur) ans+=cur;	//优先考虑原数为0 
		else if(a1&cur&&st+cur<=m)	ans+=cur,st+=cur;
	}	//若得到的数必为0,则原数默认为0 
}
int main()
{
	scanf("%d%d",&n,&m);
	a0=0; a1=(1<<30)-1;
	for(int i=1;i<=n;i++)
	{
		scanf("%s%d",ch,&t);
		if(ch[0]=='A') a0&=t,a1&=t;
		else if(ch[0]=='O') a0|=t,a1|=t;
		else a0^=t,a1^=t;
	}
	get_ans();
	printf("%d\n",ans);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值