D. Ehab and another another xor problem(Codeforces Round #525 (Div. 2))(互動題)
阿新 • • 發佈:2018-12-26
題意:這是個互動題,題意是這樣的,現在不知道a,b的值,但是有三種操作,
然後每次問完問題,也就是你輸出你的c和d,互動系統會給出相應的值(1/0/-1),然後你最多可以問62個問題,最後確定出這個a和b是多少?資料範圍:
題解:要想確定a和b的值,況且a,b的範圍最多是30位,如果可以分別確定每一位上的值,那麼a,b也就確定了,但是根據三種操作只能確定大小關係,那麼又該如何做呢?那麼一位一位比較,從低位到高位還是從高位到低位,還是從高位到低位吧,設此時已經比較到了第i位,那麼此時a,b的第i位無非有四種情況{0,0},{1,1},{1,0},{0,1},先將a,b初始化0,0,然後可以分別問這樣兩個問題(a^(1<<i),b),(a,(b^(1<<i)),如果是第一種情況,自然兩個問題問了後,回答是不一樣的,況且必然第一個回覆是1,所以此時接著比較下一位即可,對於第二種情況是,兩個回答肯定是不一樣的,況且第一個答覆是-1,所以直接將a,b進行^(1<<i),表示加上這個位子上的1,然後對於後面兩種情況,兩者的回答必然是相同的,然後當然首先要問下(0,0)的回覆,如果答覆是1,必然a要^(1<<i),否則b^(1<<i),然後將第一個回覆記錄下,為什麼,因為它實際上記錄的是從這一位開始後面的比較。
注意:
傳送門可以看這篇博文了解下fflush(stdout)的作用吧
附上程式碼:
#include<bits/stdc++.h> using namespace std; int ask(int c,int d) { printf("? %d %d\n",c,d); fflush(stdout); int ans; scanf("%d",&ans); return ans; } int main() { int a=0,b=0,big=ask(0,0); for(int i=29;i>=0;i--){ int f=ask(a^(1<<i),b),s=ask(a,b^(1<<i)); if(f==s){ if(big==1){ a^=(1<<i); }else{ b^=(1<<i); } big=f; }else if(f==-1){ a^=(1<<i); b^=(1<<i); } } printf("! %d %d\n",a,b); fflush(stdout); return 0; }