【CF1020D】The hat(交互,二分)

题意:有n个人围成一个圈,n为偶数,每个人有一个数字a[i],保证相邻两个人的数字差为1

最多可以询问60次,要求获得一个i使得a[i]=a[i+n/2]

n<=1e5,abs(a[i])<=1e9

思路:首先n不为4的倍数时奇偶性不同,无解

将+1和-1设为b[i],所求即为两段长度为n并且和为0的数列

设f(i)=a[i+n/2]-a[i]

二分答案,设当前区间为[l,r],中点为mid

若f(l)与f(mid)异号,答案若存在则(l,mid)中必定有解

若f(r)与f(mid)异号,答案若存在则(mid+1,r)中必定有解

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<string>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<vector>
11 #include<bitset>
12 using namespace std;
13 typedef long long ll;
14 typedef unsigned int uint;
15 typedef unsigned long long ull;
16 typedef pair<int,int> PII;
17 typedef vector<int> VI;
18 #define fi first
19 #define se second 
20 #define MP make_pair
21 #define N      210000
22 #define M      51
23 #define MOD 1000000007
24 #define eps 1e-8 
25 #define pi     acos(-1)
26 #define oo     3e14
27 
28 int a[N],b[N],n;
29 
30 int query(int x)
31 {
32     if(b[x]) return a[x];
33     b[x]=1;
34     printf("? %d\n",x);
35     fflush(stdout);
36     int l,r;
37     scanf("%d",&l);
38     printf("? %d\n",x+n/2);
39     fflush(stdout);
40     scanf("%d",&r);
41     if(l==r)
42     {
43         printf("! %d\n",x);
44         exit(0);
45     }
46     a[x]=r-l;
47 }
48 
49 void solve(int l,int r)
50 {
51     int mid=(l+r)>>1;
52     int sl=query(l);
53     int sr=query(r);
54     int sm=query(mid);
55     if((ll)sl*sm<0) solve(l,mid);
56      else if((ll)sr*sm<0) solve(mid+1,r);
57 }
58  
59 int main()
60 { 
61     scanf("%d",&n);
62     if(n%4) printf("! -1\n");
63      else 
64      {
65          solve(1,n/2);
66           printf("! -1\n");
67      }
68     return 0;
69 }

 

posted on 2018-12-05 17:45  myx12345  阅读(139)  评论(0编辑  收藏  举报

导航