1. 程式人生 > 遊戲 >《明末:淵虛之羽》新視覺圖 國風克蘇魯魂類ARPG

《明末:淵虛之羽》新視覺圖 國風克蘇魯魂類ARPG

起床困難綜合症

原題連結


題目描述

\([0, m]\)中找一個數,在經過\(n\)次位運算之後得到的值最大,求這個最大的值。

輸入樣例

3 10
AND 5
OR 6
XOR 7

輸出樣例

1

思路

首先,我們知道位運算是不存在進位的,所以一個位置上填1或0與其他的位置是無關的。
有了以上的結論,我們可以把問題簡化成列舉一個數它的每一位是否可以填1
如果一個位置上可以填1,這個位置必須滿足以下兩個條件:

1.填上1之後,這個數不會超過m
2.填上1之後,經過n次位運算,結果比填上0要大,假如填上0和填上1相同,我們必然要優先填0。
  因為填上0下面的位置更有可能填1而不超過m。

程式碼實現

#include <iostream>
using namespace std;

const int N = 1e5 + 10;

pair<string, int> a[N];
int n, m;

int calc(int bit, int now){
	for(int i = 0; i < n; i++){
		int x = a[i].second >> bit & 1;
		if(a[i].first == "AND") now &= x;
		if(a[i].first == "OR") now |= x;
		if(a[i].first == "XOR") now ^= x;
	}
	return now;
}
int main(){
	cin >> n >> m;
	for(int i = 0; i < n; i++) cin >> a[i].first >> a[i].second;
	int ans = 0, val = 0;
	for(int bit = 29; bit >= 0; bit--){
		int res0 = calc(bit, 0);
		int res1 = calc(bit, 1);
		if(val + (1 << bit) <= m && res0 < res1)
			val += 1 << bit, ans += 1 << bit;
		else ans += res0 << bit;
	}
	cout << ans << endl;
	return 0;
}