原题链接在这里:Problem - F - Codeforces
“交互题首先想想有没有二分的思路”——大兔子
这题挺玄学的,总共是60次问询,首先用二分定位最大值最坏用掉30次,剩下的只能靠随机抽取对应位,然后用差值之间的gcd去求公差,因为这是随机的,所以被卡的概率及其的小,(一开始直接正序问询然后被卡了),所以问询特定位的时候还是要随机操作
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 int n,a[100]; 5 bool vis[1000005]; 6 inline int gcd(int x,int y){return (y==0?x:gcd(y,x%y));} 7 int main(){ 8 int i,j,zt,low,high,mid,lef,mx,gg; 9 low=0,high=1e9; 10 scanf("%d",&n); 11 lef=60; 12 while (low<=high){ 13 mid=(low+high)>>1; 14 printf("> %d ",mid);fflush(stdout); 15 scanf("%d",&zt); 16 lef--; 17 if (zt==1){ 18 low=mid+1; 19 mx=mid; 20 } 21 else high=mid-1; 22 } 23 mx++; 24 a[0]=0; 25 a[++a[0]]=mx; 26 if (lef>=n){ 27 for (i=1;i<=min(lef,n);i++){ 28 printf("? %d ",i);fflush(stdout); 29 scanf("%d",&a[++a[0]]); 30 } 31 gg=abs(a[2]-a[1]); 32 for (i=3;i<=a[0];i++) 33 gg=gcd(gg,abs(a[i]-a[i-1])); 34 printf("! %d %d",mx-gg*(n-1),gg); 35 return 0; 36 } 37 srand((int)time(0)); 38 memset(vis,false,sizeof(vis)); 39 while (lef){ 40 zt=((LL)rand()*(LL)rand()%n*((LL)rand()*(LL)rand()%n))%n; 41 if (vis[zt]==false){ 42 lef--; 43 vis[zt]=true; 44 } 45 } 46 a[0]=0; 47 for (i=0;i<n;i++){ 48 if (vis[i]){ 49 printf("? %d ",i+1);fflush(stdout); 50 scanf("%d",&a[++a[0]]); 51 } 52 } 53 sort(a+1,a+a[0]+1); 54 gg=abs(a[2]-a[1]); 55 for (i=3;i<=a[0];i++) 56 gg=gcd(gg,abs(a[i]-a[i-1])); 57 printf("! %d %d",mx-gg*(n-1),gg); 58 return 0; 59 }