cf1088 D. Ehab and another another xor problem(位运算,交互题)

题意:

猜两个数 a 和 b,输出 ? x y 会回答 a^xb^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\) 且第 \(i-1\) 位到末尾 \(a<b\)

回答 “等于” 表示 \(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;
}

posted @ 2021-12-20 15:39  Bellala  阅读(42)  评论(0)    收藏  举报