【互動題】Codeforces 1019B The hat
阿新 • • 發佈:2018-12-24
分析:
非常簡單的互動題,二分答案的左端點位置(在[1,n/2]中)
由於每兩個相鄰的點值都相差1,所以可以把詢問的值看作一個由-1或1組成的序列的字首和。
答案就是要求兩個字首和相差為0,長度為n/2的區間。
所以二分的時候,如果當前區間的左端點值(即a[l+n/2]-a[l])與中間的值(a[mid+n/2]-a[mid])同號,則如果有答案,右端點的值(a[r+n/2]-a[r])一定與中間的值(a[mid+n/2]-a[mid])異號,每次忘異號的那個區間找即可。(因為異號的區間一定經過了0這個點)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 100010
using namespace std;
typedef long long ll;
int n,m,p,v,l,r;
int a[MAXN];
bool used[MAXN];
int ask(int x){
if(used[x])
return a[x];
used[x]=1;
PF("? %d\n",x);
fflush(stdout);
int l,r;
SF("%d",&l);
PF("? %d\n",x+n/2);
fflush(stdout);
SF("%d",&r);
if(l==r){
PF("! %d\n",x);
exit(0);
}
a[x]=r-l;
}
void que(int l,int r){
int mid=(l+r)>>1;
ll vall=ask(l);
ll valm=ask(mid);
ll valr=ask(r);
if(vall*valm<0 )
que(l,mid);
else if(valm*valr<0)
que(mid+1,r);
}
int main(){
SF("%d",&n);
if(n%4){
PF("! -1");
return 0;
}
que(1,n/2);
PF("! -1");
}