交互题
这类型不同于普通的题。
可以理解为有个问题需要你解决,你通过输入某些东西表示你要问系统的问题,这时系统会回答你的问题。在代码中的回答方式就是会输入某个东西就是系统给你的答案,通过这些信息你可以得到问题的解你是不可以自己测试的,只能提交给系统测试。
有个东西需要用到C++中的fflush(stdout);,这个东西是用来清空输出缓存区的因为你一直提问,一直输出,就需要清空输出缓存区。不然就有一些异常。
简单的理解成你在和出题人交互,你问一个问题,他回一个问题,最终你根据他的回答确定答案
题意:
一个环,初始每个数都是k ,每一秒结束每个数会将自己一半给右边(向上取整),另外一半(向下取整)给左边。
有一个数很特殊,他会把所有数给右边。
每次询问可以询问当前一个数的值
1e5个数,最多1000次询问,求这个特殊的数位置。
题解:
第一次做交互题
参考题解
通过打表可以得到:
特殊数永远都是k
且第x 秒的时候,特殊数左边x 数会小于k ,右边x 个数会大于k 。
也就是没过一秒,异常区域的左右就扩大一个单位,直到已达到左右边界为止
我们从第一个点开始询问,第i次询问后将当前点加上i,只要遇到不等于k的点说明就进入了异常区域,如果返回值大于k,说明特殊点在左边,一直往左遍历直到遇到等于k的点就好了。如果返回值小于k,说明在右边,就一直往右遍历直到找到k
最多找500次就完事了
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 5e5 + 7;
int que(int x) {
printf("? %d\n",x);
fflush(stdout);
int res;
scanf("%d",&res);
return res;
}
int main() {
int n,k;scanf("%d%d",&n,&k);
que(1);
int cur = 1;
for(int i = 1;i <= n;i++)
{
cur = (cur + i - 1) % n + 1;
int res = que(cur);
if(res != k)
{
if(res > k)
{
while(true)
{
cur = (cur == 1 ? n : cur - 1);
res = que(cur);
if(res == k) {
printf("! %d\n",cur);
fflush(stdout);
return 0;
}
}
}
else
{
while(true)
{
cur = (cur == n ? 1 : cur + 1);
res = que(cur);
if(res == k)
{
printf("! %d\n",cur);
fflush(stdout);
return 0;
}
}
}
}
}
return 0;
}