1 2 3 4

CF 1480C Searching Local Minimum

一个非常巧妙的二分题目,太强了

题目要求找一个V的最低端,100000的数组,最多询问100次,那么每次询问两个位置,如果这两个数字是递减,那么低端位置一定在右边,如果是递增,峰值一定在左边,二分就好了,

很可惜没有想出来,二分学的还是不够好

 

#include<iostream>
#include<queue>
using namespace std;
typedef long long ll;
ll ans[200000];
int vis[200000];
int ask(int x){
    
    if(vis[x]) return 0;
    cout<<"?"<<" "<<x<<endl;
    cin>>ans[x];
    return 0;
}


int main(){
    int n;
    cin>>n;
    vis[0] = vis[n+1] = 1;
    ans[0] = ans[n+1] = 1e9+1;
    
    ask(1);
    ask(2);

    
    
    
    
    int l = 1,r = n;
    int d = -1;
    
    for(int i=0;i<30;i++){
        int mid = (l+r)/2;
        ask(mid);
        ask(mid+1);
//        ask(mid-1);
        
        if(ans[mid] > ans[mid+1]){
            l = mid;
        }
        else{
            r = mid;
        }
    }
    
    
    for(int i=1;i<=n;i++){
        
        if(ans[i] == 0 || ans[i-1] == 0 || ans[i+1] == 0) continue;
        
        if(ans[i] < ans[i-1] && ans[i] < ans[i+1]){
            cout<<"!"<<" "<<i<<endl;
            return 0;
        }
    }
    
    
    return 0;
} 

 

posted @ 2021-02-10 03:08  Lesning  阅读(65)  评论(0编辑  收藏  举报