BZOJ 3668 [Noi2014]起床困难综合症

来源:互联网 发布:mac os 恢复 编辑:程序博客网 时间:2024/05/16 12:00

Description
21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳。作为一名青春阳光好少年,atm 一直坚持与起床困难综合症作斗争。通过研究相关文献,他找到了该病的发病原因:在深邃的太平洋海底中,出现了一条名为 drd 的巨龙,它掌握着睡眠之精髓,能随意延长大家的睡眠时间。正是由于 drd 的活动,起床困难综合症愈演愈烈,以惊人的速度在世界上传播。为了彻底消灭这种病,atm 决定前往海底,消灭这条恶龙。历经千辛万苦,atm 终于来到了 drd 所在的地方,准备与其展开艰苦卓绝的战斗。drd 有着十分特殊的技能,他的防御战线能够使用一定的运算来改变他受到的伤害。具体说来,drd 的防御战线由 n扇防御门组成。每扇防御门包括一个运算op和一个参数t,其中运算一定是OR,XOR,AND中的一种,参数则一定为非负整数。如果还未通过防御门时攻击力为x,则其通过这扇防御门后攻击力将变为x op t。最终drd 受到的伤害为对方初始攻击力x依次经过所有n扇防御门后转变得到的攻击力。由于atm水平有限,他的初始攻击力只能为0到m之间的一个整数(即他的初始攻击力只能在0,1,…,m中任选,但在通过防御门之后的攻击力不受 m的限制)。为了节省体力,他希望通过选择合适的初始攻击力使得他的攻击能让 drd 受到最大的伤害,请你帮他计算一下,他的一次攻击最多能使 drd 受到多少伤害。


【题目分析】
  从前到后贪心的选取,如果这一位1比0优,选1,否则选择0。如果这一位是1的话会大于m就选0。


【代码】

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;char s[101];int n,m;int opt[100001],num[100001];int main(){    int n,m;    scanf("%d%d",&n,&m);    for (int i=1;i<=n;++i)    {        scanf("%s",s+1);        if (s[1]=='A') opt[i]=1;  //&        if (s[1]=='O') opt[i]=2;  //|        if (s[1]=='X') opt[i]=3;  //^        scanf("%d",&num[i]);    }    int ans=0;    for (int i=31;i>=0;--i)    {        if (ans+(1<<i)>m) continue;        int ans1=ans+(1<<i),ans0=ans;        for (int j=1;j<=n;++j)        {            if (opt[j]==1) ans1&=num[j];            if (opt[j]==2) ans1|=num[j];            if (opt[j]==3) ans1^=num[j];            if (opt[j]==1) ans0&=num[j];            if (opt[j]==2) ans0|=num[j];            if (opt[j]==3) ans0^=num[j];        }        int x=(ans1)&(1<<i),y=(ans0)&(1<<i);        if (x>y) ans+=(1<<i);    }       for (int j=1;j<=n;++j)    {        if (opt[j]==1) ans&=num[j];        if (opt[j]==2) ans|=num[j];        if (opt[j]==3) ans^=num[j];    }    cout<<ans<<endl;}
0 0
原创粉丝点击