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
1 -1 0
Output
? 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.
题意:在62次查询内找出a,b
题解:30位, 一位一位判断就行了,分别异或0 1 和 1 0,若结果不同,这位肯定都为1或0,若相同,说明a和b在这一位的数字不同,那么我们就让a,b分别异或他们之前都判断出来的位,若结果为1,那么就是a这一位为1,b这一位为0,结果为-1,反之
但是这样很有可能就超出62次了,那我们记录下从这一位开始,只比较 a,b 后面的位的大小,这样判断到每一位的时候,若第一次和第二次查询结果相同,就直接判断即可,详见代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define PI acos(-1)
const int N = 2100+10;
int a, b;
int main() {
int op1, op2, flag = 0;
int c, d;
for(int i = 29; i >= 0; i--) {
c = a + (1<<i);
d = b;
printf("? %d %d\n", c, d);fflush(stdout);
scanf("%d", &op1);
c = a;
d = b + (1<<i);
printf("? %d %d\n", c, d);fflush(stdout);
scanf("%d", &op2);
if(op1 == -1 && op2 == 1) {
a += (1<<i);
b += (1<<i);
} else if(op1 == 1 && op2 == -1) {
a += 0;
b += 0;
} else {
if(flag == 0) { // 这一步最多进行一次
printf("? %d %d\n", a, b);fflush(stdout);
scanf("%d", &flag);
}
if(flag == 1) {
a += (1<<i);
b += 0;
flag = op1; // 记录后面大小
} else {
a += 0;
b += (1<<i);
flag = op2; // 记录后面大小
}
}
}
printf("! %d %d\n", a, b);fflush(stdout);
return 0;
}