Strange Shuffle CodeForces - 1471E(交互题)
交互题
这类型不同于普通的题。
可以理解为有个问题需要你解决,你通过输入某些东西表示你要问系统的问题,这时系统会回答你的问题。在代码中的回答方式就是会输入某个东西就是系统给你的答案,通过这些信息你可以得到问题的解你是不可以自己测试的,只能提交给系统测试。
有个东西需要用到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; }
codeforces 文章被收录于专栏
codeforces题目分析