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

D. Ehab and another another xor problem

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

This is an interactive problem!

Ehab plays a game with Laggy. Ehab has 2 hidden integers (a,b)(a,b). Laggy can ask a pair of integers (c,d)(c,d) and Ehab will reply with:

  • 1 if a⊕c>b⊕da⊕c>b⊕d.
  • 0 if a⊕c=b⊕da⊕c=b⊕d.
  • -1 if a⊕c<b⊕da⊕c<b⊕d.

Operation a⊕ba⊕b is the bitwise-xor operation of two numbers aa and bb.

Laggy should guess (a,b)(a,b) with at most 62 questions. You'll play this game. You're Laggy and the interactor is Ehab.

It's guaranteed that 0≤a,b<2300≤a,b<230.

Input

See the interaction section.

Output

To print the answer, print "! a b" (without quotes). Don't forget to flush the output after printing the answer.

Interaction

To ask a question, print "? c d" (without quotes). Both cc and dd must be non-negative integers less than 230230. Don't forget to flush the output after printing any question.

After each question, you should read the answer as mentioned in the legend. If the interactor replies with -2, that means you asked more than 62 queries and your program should terminate.

To flush the output, you can use:-

  • fflush(stdout) in C++.
  • System.out.flush() in Java.
  • stdout.flush() in Python.
  • flush(output) in Pascal.
  • See the documentation for other languages.

Hacking:

To hack someone, print the 2 space-separated integers aa and bb (0≤a,b<230)(0≤a,b<230).

Example

input

Copy

1
-1
0

output

Copy

? 2 1
? 1 2
? 2 0
! 3 1

Note

In the sample:

The hidden numbers are a=3a=3 and b=1b=1.

In the first query: 3⊕2=13⊕2=1 and 1⊕1=01⊕1=0, so the answer is 1.

In the second query: 3⊕1=23⊕1=2 and 1⊕2=31⊕2=3, so the answer is -1.

In the third query: 3⊕2=13⊕2=1 and 1⊕0=11⊕0=1, so the answer is 0.

Then, we printed the answer.

题意:又是个互动题,现在你的对手有两个数字c和d,你每次询问a,b两个数,他会告诉你a^c和b^d哪个大,前者大他会给你输入1,后者大他会给你输入-1。让你在62次询问之内确定c和d的大小,输出格式见上。

思路:

显然是两次询问确定两个数二进制的一位,从而确定这两个数的二进制的30位是0还是1。不过我确定没想到构造方法。赛后看了别人的代码。

首先直接询问0 0,就可以知道a和b的大小。(是否用到先不管,因为我们还是很容易看出这个结论的)

设x=0,y=0。

从最高位开始(因为从最低位无法通过大小确定每一位),分别询问

c=(x,y|(1<<i))和 d=(x|(1<<i),y)

好好思考一下为什么要这样询问。

如果c==1&&d==-1,那么显然a和b的第i位都为1,反之则为0.

否则与从当前位开始a的后i位和b的后i位的大小有关,设为aa和bb

如果aa>bb 则a的第i位为1,b的第i位为0,反之同理。

然后根据c的值更新a和b哪个大哪个小即可。这个时候刚开始的0 0询问就有用了,再用一个变量表示aa和bb的大小即可。

在纸上画一画好好想想。

代码:

#include <bits/stdc++.h>
using namespace std;
int go(int a,int b)
{
    cout<<"? "<<a<<" "<<b<<endl;
    int x;
    cin>>x;
    return x;
}
int main()
{
    int x=0,y=0;
    int ac=go(x,y);
    for(int i=29;i>=0;i--)
    {
        int c=go(x,y|(1<<i)),d=go(x|(1<<i),y);
        if(c==1&&d==-1)
        {
            x|=(1<<i);
            y|=(1<<i);
        }
        else if(c==-1&&d==1)
        {
            x=x;
            y=y;
        }
        else
        {
            if(ac==1) x|=(1<<i);
            else y|=(1<<i);
            ac=(c==1);
        }
    }
        cout<<"! "<<x<<" "<<y<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/84978217