《明末:淵虛之羽》新視覺圖 國風克蘇魯魂類ARPG
阿新 • • 發佈:2021-09-18
起床困難綜合症
原題連結
題目描述
在\([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; }