Codeforces Round #525 (Div. 2) D. Ehab and another another xor problem 交互 二进制 思维

题解

交互题
题目大意 有两个数字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;
}

猜你喜欢

转载自blog.csdn.net/CaprYang/article/details/84836624