cf 843 B Interactive LowerBound [随机化]

题面:

传送门

思路:

这是一道交互题

比赛的时候我看到了直接跳过了......

后来后面的题目卡住了就回来看这道题,发现其实比较水

实际上,从整个序列里面随机选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 }
原文地址:https://www.cnblogs.com/dedicatus545/p/8455292.html