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

版权声明:没人会转的( ̄▽ ̄) https://blog.csdn.net/j2_o2/article/details/84826238
题目链接
题意

存在两个未知数a,b你可以通过一系列问题(交互,询问不超过62次)求得a,b是什么
询问方式给交互姬,两个整数c,d
a ^ c > b ^ d,交互姬返回1
a ^ c = b ^ d,交互姬返回0
a ^ c < b ^ d,交互姬返回-1

思路

当时想询问62次,a,b二进制才30位,大概可以先确定最高位,每两次询问确定a和b的一位,从高到底可以无影响的判断下去。
大致思路如此,我忽略了。。低位对高位是存在影响(如果当前位a ^ c = b ^ d那么低位会产生影响)
所以我们可以最初先查询?0 0,来判断低位的影响(如何判断下面提)。

每位查询询问两次,?表示低位有影响

对于每位查询 a=0,b=0 a=0,b=1 a=1,b=0 a=1,b=1
c=1,d=0,值为flag1 1 ? ? -1
c=0,d=1,值为flag2 -1 ? ? 1

上表没有突出
1.忽略高位
2.如果(a=0,b=1 )和 (a=1,b=0),那么两次查询结果相同,这里可以想一想。


所以

if(flag1 != flag2)
{
    if(flag1 == -1) a = 1, b = 1;
    if(flag1 == 1) a = 0, b = 0;
}

对于?即flag1 == flag2 的情况:
我们最先查询? 0 0,用wtf记录返回值。
如果是?说明这位两者当前位不同,两个二进制不同最高位,一定能决定谁大谁小。
所以根据wtf来判断01情况,记得每次这样判断完都要更新wtf,因为要保证比较的是两个二进制不同最高位
wtf更新为flag1,因为flag1表示了当前位无影响时,低位谁打谁小。
详见代码


代码
#include <stdio.h>

int main()
{
    int a = 0, b = 0;

    printf("? 0 0\n"); fflush(stdout); int wtf; scanf("%d",&wtf);

    for(int i = 29; ~i; --i)
    {
        printf("? %d %d\n",(1<<i)+a,(0<<i)+b); fflush(stdout); int flag1; scanf("%d",&flag1);
        printf("? %d %d\n",(0<<i)+a,(1<<i)+b); fflush(stdout); int flag2; scanf("%d",&flag2);

        if(flag1 == flag2)
        {
            if(wtf == 1) a += (1<<i);
            else b += (1<<i);
            wtf = flag1;
        }
        else if(flag1 == -1) a += (1<<i), b += (1<<i);
    }
    printf("! %d %d\n",a, b);
    fflush(stdout);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/j2_o2/article/details/84826238
今日推荐