题面:
思路:
这是一道交互题
比赛的时候我看到了直接跳过了......
后来后面的题目卡住了就回来看这道题,发现其实比较水
实际上,从整个序列里面随机选1000个数出来询问,然后从里面找出比x小的最大的那个,再往后面搜1000个数(顺序),这样的方法,不成功率是1.7e-9......
所以随机化就可以了~
(要是这样还WA那真的是脸黑呢......)
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<ctime> 6 using namespace std; 7 int n,st,x; 8 int val[50010],next[50010]; 9 int cnt; 10 struct node{ 11 int v,p; 12 }s[2010]; 13 bool cmp(node l,node r){ 14 return l.v<r.v; 15 } 16 int main(){ 17 int i,tmp,ttmp,t1,t2; 18 srand(time(NULL)); 19 scanf("%d%d%d",&n,&st,&x); 20 printf("? %d",st); 21 scanf("%d%d",&t1,&t2); 22 if(x<t1){ 23 printf("! -1");return 0; 24 } 25 val[st]=t1;next[st]=t2; 26 for(i=2;i<=min(1005,n);i++){ 27 tmp=rand()*rand()%n+1; 28 printf("? %d",tmp); 29 scanf("%d%d",&t1,&t2); 30 s[++cnt].v=t1;s[cnt].p=tmp; 31 val[tmp]=t1;next[tmp]=t2; 32 } 33 sort(s+1,s+cnt+1,cmp); 34 for(i=1;i<cnt;i++){ 35 if(s[i].v<x&&s[i+1].v>=x) break; 36 } 37 tmp=s[i].p; 38 if(n<=1005){ 39 printf("! %d",val[tmp]);return 0; 40 } 41 for(i=1006;i<=1999;i++){ 42 ttmp=next[tmp]; 43 printf("? %d",ttmp); 44 scanf("%d%d",&val[ttmp],&next[ttmp]); 45 if(val[ttmp]>=x){ 46 printf("! %d",val[tmp]);return 0; 47 } 48 tmp=ttmp; 49 } 50 }