D. Ehab and another another xor problem(位運算,互動題)
阿新 • • 發佈:2021-12-20
題意:
猜兩個數 a 和 b,輸出 ? x y
會回答 a^x
和 b^y
的大小關係(1,0,-1分別表示大於等於小於)。
\(0\le a,b < 2^{30}\),詢問次數不能超過62次
思路:
假設比 \(i\) 高的位都已經確定,而且要求 \(i\) 到末尾 \(a>b\) 。
以下的 \(a\) 表示最高位到第 \(i+1\) 位已確定,其他位為0。\(b\) 同理。
先詢問 ? a|(1<<i) b
,
回答 “大於” 表示只有兩種可能:① \(a_i=b_i=0\) ;或者 ② \(a_i\neq b_i\) 且第 \(i-1\) 位到末尾 \(a>b\)
回答 “小於” 表示只有兩種可能:① \(a_i=b_i=1\)
回答 “等於” 表示 \(a_i\neq b_i\),字尾相等,這種情況可以不用管
再詢問 ? a b|(1<<i)
,
回答 “大於” 表示只有兩種可能:① \(a_i=b_i=1\) ;或者 ② \(a_i\neq b_i\) 且第 \(i-1\) 位到末尾 \(a>b\)
回答 “小於” 表示只有兩種可能:① \(a_i=b_i=0\) ;或者 ② \(a_i\neq b_i\) 且第 \(i-1\) 位到末尾 \(a<b\)
回答 “等於” 同上,而且等於肯定是成對出現的
綜上,若回答 > <
則 \(a_i=b_i=0\),若回答 < >
則 \(a_i=b_i=1\),若回答兩個大於或兩個小於則要考慮比 \(i\) 高的位對 \(i\) 的要求。
#include <bits/stdc++.h> using namespace std; int ask(int x, int y) { cout << "? " << x << " " << y << endl; cin >> x; return x; } signed main() { int a = 0, b = 0, flag = ask(0, 0); //對低位的要求 for(int i = 29; i >= 0; i--) { int t1 = ask(a|(1<<i), b), t2 = ask(a, b|(1<<i)); if(t1 == t2) { if(flag == 1) a |= (1<<i); else b |= (1<<i); flag = t1; } else if(t1 == -1) a |= (1<<i), b |= (1<<i); } cout << "! " << a << " " << b << endl; return 0; }