题目如题
C++ 代码
#include <iostream>
using namespace std;
const int N = 1e5 + 5;
pair<string, int> a[N];
int n, m;
// 计算val的第b位的值,通过n扇门后的攻击值
int calc(int b, int v) {
for(int i = 0; i < n; i++) {
string s = a[i].first; // 取位操作符
int t = a[i].second >> b & 1; // 取攻击值的第i位
// 根据提供的位操作对攻击值的第i位进行相应的操作
if(s == "AND") v &= t;
else if(s == "OR") v |= t;
else v ^= t;
}
return v;
}
int dfs(int val, int ans, int k) {
if(k < 0) return ans;
int t = val | 1 << k;
int x = calc(k, 0);
int y = calc(k, 1);
int u = ans | x << k;
int v = ans | y << k;
if(t > m || u >= v) ans = u;
else val = t, ans = v;
ans = dfs(val, k - 1, ans);
}
int main() {
cin >> n >> m;
for(int i = 0; i < n; i++) // 初始化
cin >> a[i].first >> a[i].second;
int ans = 0, val = 0; // 通过n扇门后的攻击值,初始攻击值
cout << dfs(val, ans, 29);
return 0;
}
#include <iostream>
using namespace std;
const int N = 1e5 + 5;
pair<string, int> a[N];
int n, m;
// 计算val的第b位的值,通过n扇门后的攻击值
int calc(int b, int v) {
for(int i = 0; i < n; i++) {
string s = a[i].first; // 取位操作符
int t = a[i].second >> b & 1; // 取攻击值的第i位
// 根据提供的位操作对攻击值的第i位进行相应的操作
if(s == "AND") v &= t;
else if(s == "OR") v |= t;
else v ^= t;
}
return v;
}
int main() {
cin >> n >> m;
for(int i = 0; i < n; i++) // 初始化
cin >> a[i].first >> a[i].second;
int ans = 0, val = 0; // 通过n扇门后的攻击值,初始攻击值
for(int i = 29; i >= 0; i--) {
int x = calc(i, 0); // 在val第i位填0,通过n扇门后该位的值
int y = calc(i, 1); // 在val第i位填1,通过n扇门后该位的值
int t = val | 1 << i; // val的第i位填1的结果
int u = ans | x << i; // 在val第i位填0,可能要累积到ans中的攻击值
int v = ans | y << i; // 在val第i位填1,可能要累积到ans中的攻击值
// val的第i位填1导致val不在[1,m]内
// 或者在val第i位填0比填1导致累计结果的值更大
if(t > m || u >= v) ans = u; // 在val第i位填0,累计到答案中
else val = t, ans = v; // 否则,在val第i位填1,累计到答案中
}
cout << ans;
return 0;
}
算法2
(暴力枚举) $O(n^2)$
blablabla
时间复杂度
参考文献
C++ 代码
blablabla
好评!