您的位置:首页 > 其它

cf 843 B Interactive LowerBound [随机化]

2018-02-20 15:51 417 查看
题面:

传送门

思路:

这是一道交互题

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

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

实际上,从整个序列里面随机选1000个数出来询问,然后从里面找出比x小的最大的那个,再往后面搜1000个数(顺序),这样的方法,不成功率是1.7e-9......

所以随机化就可以了~

(要是这样还WA那真的是脸黑呢......)

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
int n,st,x;
int val[50010],next[50010];
int cnt;
struct node{
int v,p;
}s[2010];
bool cmp(node l,node r){
return l.v<r.v;
}
int main(){
int i,tmp,ttmp,t1,t2;
srand(time(NULL));
scanf("%d%d%d",&n,&st,&x);
printf("? %d",st);
scanf("%d%d",&t1,&t2);
if(x<t1){
printf("! -1");return 0;
}
val[st]=t1;next[st]=t2;
for(i=2;i<=min(1005,n);i++){
tmp=rand()*rand()%n+1;
printf("? %d",tmp);
scanf("%d%d",&t1,&t2);
s[++cnt].v=t1;s[cnt].p=tmp;
val[tmp]=t1;next[tmp]=t2;
}
sort(s+1,s+cnt+1,cmp);
for(i=1;i<cnt;i++){
if(s[i].v<x&&s[i+1].v>=x) break;
}
tmp=s[i].p;
if(n<=1005){
printf("! %d",val[tmp]);return 0;
}
for(i=1006;i<=1999;i++){
ttmp=next[tmp];
printf("? %d",ttmp);
scanf("%d%d",&val[ttmp],&next[ttmp]);
if(val[ttmp]>=x){
printf("! %d",val[tmp]);return 0;
}
tmp=ttmp;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: