版权声明:禁止商业用途,如需转载请注明原文出处:https://hyp1231.github.io 或者 https://blog.csdn.net/hyp1231/article/details/81263335
建议访问原文出处,获得更佳浏览体验。
原文出处:https://hyp1231.github.io/2018/07/28/20180728-cf1010b/
题意
交互式题目,通过和机器的沟通猜一个正整数
。
每次你询问一个正整数
,机器理应返回的正确答案为
但是机器有些故障,他有时返回和正确答案互为相反数的结果,这个规律通过长度为
的数列
描述。数列
的每一项是
或者是
。对于第
次询问,如果数列的第
项是
,则返回相反的答案;否则返回正确答案。
现在你可以给出最多
次询问,根据机器返回的值确定这个要猜测的数字
。
链接
题解
考虑询问为
时,正确答案只能为
或
。由于
不超过
,因此我们的前
次询问可以全部为
,这样就可以知道数列
的每一项的值。
自此,机器返回的每个结果都可以根据数列
的值进行调整,可以确保得到正确信息。因此我们只需要在
之间二分,即可在剩余
步内得到
的值。(
)
代码
#include <iostream>
const int N = 32;
int n, m;
int p[N];
int ask(int a) {
std::cout << a << std::endl;
fflush(stdout);
int tmp;
std::cin >> tmp;
return tmp;
} // 询问 a,return 机器的返回值
void solve(int l, int r, int cur) {
int mid = (l + r) >> 1;
int ans = ask(mid) * p[cur % n];
if (ans == 0) exit(0);
else if (ans == -1) solve(l, mid, cur + 1);
else solve(mid + 1, r, cur + 1);
} // 第 cur 次询问
int main() {
std::cin >> m >> n;
for (int i = 0; i < n; ++i) {
p[i] = ask(1);
if (p[i] == 0) exit(0); // 如果正确答案就是 1,退出程序
}
solve(1, m, 0);
return 0;
}