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

    xiaoxiao2025-02-07  8

    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; }
    转载请注明原文地址: https://ju.6miu.com/read-1296185.html
    最新回复(0)