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