1. 程式人生 > >D. Ehab and another another xor problem(Codeforces Round #525 (Div. 2))(互動題)

D. Ehab and another another xor problem(Codeforces Round #525 (Div. 2))(互動題)

傳送門

題意:這是個互動題,題意是這樣的,現在不知道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;
}