《算法竞赛进阶指南》-AcWing-998. 起床困难综合症-题解
Posted Tisfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法竞赛进阶指南》-AcWing-998. 起床困难综合症-题解相关的知识,希望对你有一定的参考价值。
起床困难综合症
题目描述
为了打败起床困难综合症去打败睡眠boss,boss有 n n n扇防御门,每扇门包含一个运算符( O R 、 X O R 、 A N D OR、XOR、AND OR、XOR、AND)和一个运算数(非负整数),攻击经过这扇门后将与门进行相应的运算操作。
勇士的初始攻击力只能是 [ 0 , m ] [0,m] [0,m]之间的一个整数,门及其摆放是固定的,勇士想通过合适的攻击以对boss照成最大的伤害。
输入样例
3 10
AND 5
OR 6
XOR 7
解释:一共 3 3 3扇门,初始攻击在 0 0 0~ 10 10 10之间,第一扇门将与攻击和5进行与运算,第二扇将第一扇运算后的结果与6进行或操作,最后一扇门将前面的结果与7进行异或。
样例输出
1
解释:假设初始攻击力为 4 ( 0 ≤ 4 ≤ 10 ) 4(0\\leq4\\leq10) 4(0≤4≤10),则经过如下运算:
4 AND 5 = 4
4 OR 6 = 6
6 XOR 7 = 1
获得最终攻击力为1。在 0 0 0~ 10 10 10中找不到另外一个数使得最终运算的结果大于 1 1 1。
解题思路
攻击力的每一位与另一位互不影响。 且 1 0 9 10^9 109的数据不超过 30 30 30位。
我们只需要分别看每一位(0和1两种情况),如果这一位是 1 1 1通过所有门后将会变成什么、如果是 0 0 0又会变成什么。
- 当然,我们希望最终攻击尽可能大,这就需要我们先从高位开始计算;
- 我们希望初始攻击尽可能小(需要不超过
m
m
m),这就需要满足以下两个条件时才让这一位的初始攻击力为
1
1
1:
- 这一位初始为 1 1 1的最终攻击力大于初始为 0 0 0的最终攻击力
- 这一位初始为 1 1 1的话目前初始攻击力不超过最大攻击力 m m m
更多解释请见代码注释
AC代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
string op[100010];
int num[100010];
int n;
int calculate(int wei, int thisBit) // 计算初始攻击的第wei位初始值位thisBit时,通过所有门后的最终攻击力
{
for(int i=0;i<n;i++) // 每扇门
{
int thisBit2=num[i]>>wei&1; // 取出这扇门的操作数的这一位
if(op[i]=="AND")thisBit&=thisBit2; // 如果这扇门的AND,就做与运算
else if(op[i]=="OR")thisBit|=thisBit2; // OR就做或运算
else thisBit^=thisBit2; // 否则异或运算
}
return thisBit; // 返回这一位经过所有门后最终的值
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int m;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>op[i]>>num[i];
int ans=0, original=0;
for(int i=29;i>=0;i--) // 从大到小分析每一位
{
int one=calculate(i, 1); // 如果这一位的初始攻击力是1,最终攻击力将会是one
int zero=calculate(i, 0); // 如果这一位的初始攻击力是0,最终攻击力将会是zero
if(original+(1<<i)<=m&&one>zero) // 如果这一位为1的话初始攻击力<=m 并且 这一位为1的话最终攻击力大于这一位为0的话的最终的攻击力
original+=1<<i, ans+=one<<i; // 那么这一位初始攻击力设为1,初始攻击力加上这一位,最终攻击力加上这一位为1的时候产生的最终攻击力one
else
ans+=zero<<i; // 否则这一位初始攻击力为0,最终攻击力加上这一位初始值为0的时候产生的最终的攻击力zero
}
cout<<ans<<endl; // 输出答案
return 0;
}
原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/119220647
以上是关于《算法竞赛进阶指南》-AcWing-998. 起床困难综合症-题解的主要内容,如果未能解决你的问题,请参考以下文章