题意:交互式的题,给你n,s, x,链表元素有n个,开始的位置是s,每次询问输入数组的下标,可以知道对应链表上的数和链表下一个数的位置,只能询问2000次,要找到第一个大于等于x的数
题解:先随机找小于n的1000个数,询问每一个下标,找到大小与x最近的数,再从这个数沿着链表向后找,直到找到第一个大于等于x的数或者找到链表的结尾。。。
概率分析:假设经过上面的操作后找不到答案,设x数组的下表为t,那么随机的1000个数就是都不在[t-1000, t]当中,所有数都不在的概率也就是找不到答案的概率就是(1-1000/n)^1000是一个很小的数。
这里用到了random_shuffle函数,作用是找一个该数组的全排列
#include<bits/stdc++.h> using namespace std; int n,x,v,ne,t=-1,q[50010], cnt, st; int main(){ scanf("%d%d%d",&n,&st,&x); for(int i=0;i<n;i++) q[i] = i+1; random_shuffle(q, q+n); cnt = min(n, 999); for(int i=0;i<cnt;++i){ printf("? %d\n",q[i]); fflush(stdout); scanf("%d%d",&v,&ne); if(v<=x&&t<v) t=v,st=ne; } while(st!=-1&&t<x){ printf("? %d\n",st); fflush(stdout); scanf("%d%d",&v,&ne); t=v;st=ne; } if(t<x) printf("! -1\n"); else printf("! %d\n", t); fflush(stdout); return 0; }