题意:
交互题目,在有限的询问中找到一个x,使得数列中的第x位和第(x+n/2)位的值大小相同。数列保证相邻的两个差值为1或-1;
思路:
构造函数f(x) = a[x] - a[x + n/2] ,由于a数列差值为1或-1,所以可以发现f(x)是连续的。然后就可以用二分了,这种二分的check方式是自己第一次见的。就是通过f(mid)和f(d)的正负来判断区间的移动。其中d是任选的。
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <map> #include <set> #include <queue> #include <list> #include <cstdlib> #include <iterator> #include <cmath> #include <iomanip> #include <bitset> #include <cctype> using namespace std; //#pragma GCC optimize(3) //#pragma comment(linker, "/STACK:102400000,102400000") //c++ #define lson (l , mid , rt << 1) #define rson (mid + 1 , r , rt << 1 | 1) #define debug(x) cerr << #x << " = " << x << " "; #define pb push_back #define pq priority_queue typedef long long ll; typedef unsigned long long ull; typedef pair<ll ,ll > pll; typedef pair<int ,int > pii; //priority_queue<int> q;//这是一个大根堆q //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q #define fi first #define se second //#define endl ' ' #define OKC ios::sync_with_stdio(false);cin.tie(0) #define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行 #define REP(i , j , k) for(int i = j ; i < k ; ++i) //priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //2147483647 const ll nmos = 0x80000000; //-2147483648 const int inf = 0x3f3f3f3f; const ll inff = 0x3f3f3f3f3f3f3f3f; //18 const double PI=acos(-1.0); template<typename T> inline T read(T&x){ x=0;int f=0;char ch=getchar(); while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x=f?-x:x; } // #define _DEBUG; //*// #ifdef _DEBUG freopen("input", "r", stdin); // freopen("output.txt", "w", stdout); #endif /*-----------------------show time----------------------*/ const int maxn = 1e5+9; ll f[maxn]; int n; void get(int m){ int x,y; // cout<<"? "<<m<<endl; printf("? %d ",m); fflush(stdout); scanf("%d", &x); // cout<<"? "<<m+n/2<<endl; // cin>>y; printf("? %d ",m + n/2); fflush(stdout); scanf("%d", &y); f[m] = y - x; } int main(){ // cin>>n; scanf("%d", &n); int le = 1, ri = n/2; get(1); if(f[1]==0){ printf("! 1 "); fflush(stdout); } while(le<=ri){ int mid = (le + ri) / 2; get(mid); if(f[mid]==0){ printf("! %d ",mid); fflush(stdout); return 0; } if(f[1]>0){ if(f[mid]>0){ le = mid+1; } else ri = mid - 1; } else { if(f[mid]<0){ le = mid+1; } else ri = mid - 1; } } printf("! -1 "); fflush(stdout); return 0; }