题解
交互题
题目大意 有两个数字a和b要你去猜 你可以询问两个数字c和d 系统会反馈给你a ^ c和b ^ d的大小比较结果 左边大1右边大-1相同0 最多猜62次
数值范围小于2的30次方 说明最多有30个二进制位 最开始使用一次确定a和b的大小关系 每个二进制位使用两次猜测 最后使用一次回答答案
从高到低遍历二进制位 之前的位被异或掉了当前位就是最高位 起着决定性的作用 考虑当前位的状态 具体看备注
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
int Ask(int a, int b)
{
printf("? %d %d\n", a, b);
fflush(stdout);
int res;
scanf("%d", &res);
return res;
}
int main()
{
#ifdef LOCAL
//freopen("C:/input.txt", "r", stdin);
#endif
int a = 0, b = 0;
bool Abig = Ask(0, 0) == 1; //a大
for (int i = 29; i >= 0; i--) //枚举二进制位 前面的已经被异或掉 当前位为最高位起决定性作用
{
int w = 1 << i; //当前位
int l = Ask(a | w, b); //a异或当前位后的结果
int r = Ask(a, b | w); //b
if (l == 1 && r == -1) //如果a和b异或完都增大则当前位都为0
true; //本身就是0
else if (l == -1 && r == 1) //异或完了都变小则当前为都为1
a |= w, b |= w; //对应位置置为1
else //一个为1一个为0
{
if (Abig) //谁大谁为1
a |= w;
else
b |= w;
Abig = l == 1; //相同时不变 只变不同 异或了一个之后一定相同 只需要判断异或一个哪个大
}
}
printf("! %d %d\n", a, b);
return 0;
}