Codeforces Round #700 (Div. 2) C. Searching Local Minimum(交互题+二分)

题意:
有一个长度为n的全排列,每次可以询问一个位置的值,最多询问一百次,求出 k 满足 a[k]<a[k+1],a[k]<a[k-1]。

第一次比赛写交互题,蒙了,然后随机数冲了一发,过了,最后意料之中的fst,o(╥﹏╥)o。

思路:
假如某个区间(l,r) 存在 a[i]<a[i+1],那么肯定(l,i)这个区间存在 a[i]<a[i+1],
反之,假如存在a[i]>a[i+1],那么区间 (i+1,r) 肯定存在a[i]<a[i-1] ,那么一直二分到最后,l=r的时候,a[l]必定满足 a[l]<a[l+1]&&a[l]<a[l-1](a[0]和a[n+1]都是无穷大)。

代码:

#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
#define DEV_RND ((int)rand()*RAND_MAX+rand())
#define RND(L,R) (DEV_RND%((R)-(L)+1)+(L))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int>pii;
const int MAXN=1e5+5;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
int a[MAXN];
int n;
void get(int x)
{
    
    
    if(x==0||x==n+1||a[x]) return ;
    cout<<"?"<<" "<<x<<endl;
    cin>>a[x];
}
int main()
{
    
    
    cin>>n;
    a[0]=1e9;
    a[n+1]=1e9;
    int l=1,r=n;
    while(l<r)
    {
    
    
        int mid=(l+r)/2;
        get(mid);
        get(mid+1);
        if(a[mid]<a[mid+1]) r=mid;
        else l=mid+1;
    }
    cout<<"!"<<" "<<l<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_45755679/article/details/113755930