题意:

给定了所有的防御门运算符op和参数t,限定最大的初始攻击力为m,求经过防御门转变后最大一次能对恶龙造成多少伤害

思路:

为了方便描述,我们记初始伤害为图片说明, 经过防御门以后的伤害为图片说明

既然防御门涉及到位运算,那干脆把图片说明 也表达为二进制,把问题转换成找到如何安排每一个bit的值,让图片说明的值最大

首先我们清楚:二进制中(如 0110 1001),越靠左的bit权值越大,其转换成十进制时对数的大小影响也越大。

为了能让图片说明最大,我们应尽可能让图片说明中靠左的bit为1,且1的数量尽可能多。
如果我们从最右的bit开始遍历图片说明,那么会容易让图片说明超出范围,带来很多不必要的计算,所以我们应该先让图片说明图片说明 开始,向下递减计算。

在写代码的时候,为了方便,我让图片说明从1<<30 (大于图片说明 )开始,让图片说明不断右移,直到 图片说明 ,并记录图片说明最高位1的位置

接下来,从最高位1开始,先判断如果将当前位的bit取反以后会不会超出限制(可能这步赘余了,我没仔细想,但思路是这么个思路),在确保不超出限制的情况下,再判断将bit取反以后是否能让图片说明变大,如果可以,就对该位的bit取反,对所有的bit进行相同操作。

对所有bit操作完以后,我们就得到了一个最大的图片说明

代码:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

//计算并返回num经过所有的防御门后的值
inline int crossTheDoors(int num, vector<vector<int>> &door) {
    for (auto &i : door) {
        if (i[0] == 1) {
            num |= i[1];
        } else if (i[0] == 2) {
            num ^= i[1];
        } else if (i[0] == 3) {
            num &= i[1];
        }
    }
    return num;
}

int main() {
    string temp;   //工具人变量
    int n;  //防御门的数量
    int m;  //攻击力的最大值
    cin >> n >> m;
    /*二维数组door
    door[i][0]表示运算符,1为OR,2为XOR,3为AND
    door[i][1]表示对应的t*/
    vector<vector<int>> door(n, vector<int>(2));
    for (int i = 0; i < n; ++i) {
        cin >> temp;
        if (temp == "OR") {
            door[i][0] = 1;
            cin >> door[i][1];
        } else if (temp == "XOR") {
            door[i][0] = 2;
            cin >> door[i][1];
        } else if (temp == "AND") {
            door[i][0] = 3;
            cin >> door[i][1];
        }
    }
    int x = (1 << 30);
    int bitCount = 30;  //用于找到x中bit为1的最高位
    while (x > m) {
        x >>= 1;
        bitCount--;
    }
    while (bitCount >= 0) {
        //如果当前bit是0,且把他改成1后会大于m,则跳过
        if ((x & (1 << bitCount)) == 0) {
            if ((x | (1 << bitCount)) > m) {
                bitCount--;
                continue;
            }
        }
        //看看当前bit取反以后攻击会不会更大
        if (crossTheDoors((x ^ (1 << bitCount)), door) > crossTheDoors(x, door)) {
            x ^= (1 << bitCount);
        }
        bitCount--;
    }
    cout << crossTheDoors(x, door);
}