C2. Guessing the Greatest (hard version) 二分 交互题
C2. Guessing the Greatest (hard version) 二分 交互题
题目大意:
给你一个大小为 n 的序列,保证这 n 个数互不相同,每次询问一个区间 \([l,r] \,\,l<=r\) ,返回这个区间的次大值的位置,要求你在 20 次询问内求出 \([1,n]\) 的最大值。
题解:
一开始想岔了,直接说说正确思路吧。
- 首先求一个 \([1,n]\) 的区间次大值的位置 \(p\),然后判断一下最大值在哪个区间 \([1,p]\) 还是 \([p,n]\)
- 求出之后,直接二分最大值的位置即可,以区间 \([1,p]\) 为例,如果 \([x,p]\) 的次大值 等于 \(p\) ,那么就说明最大值在区间 \(x\) 到 \(p\) ,如果不等于 \(p\) 说明最大值不在区间 \([x,p]\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int ask(int l,int r){
printf("? %d %d\n",l,r);
fflush(stdout);
int ans;
scanf("%d",&ans);
return ans;
}
int main(){
int n;
scanf("%d",&n);
int p = ask(1,n);
if(p>1&&ask(1,p)==p){
int l = 1,r = p;
while(r-l>1){
int mid = (l+r)>>1;
if(ask(mid,p)==p) l = mid;
else r = mid;
}
printf("! %d\n",l);
}
else {
int l = p,r = n;
while(r-l>1) {
int mid = (l + r) >> 1;
if (ask(p,mid) == p) r = mid;
else l = mid;
}
printf("! %d\n",r);
}
return 0;
}