codeforces 1480 C Searching Local Minimum (交互题+二分)

题面

在这里插入图片描述
在这里插入图片描述

题意

  1. 交互题,输入一个n,会有一个序列(序列中的数就是1…n乱序排列),然后你可以询问最多100次,来找出序列中一个局部最小值(就是这个数小于它左右两边的数)
  2. 模拟样例:输入一个n =5, 然后程序问你 下标为3 的位置数的值,然后你输入1 ,然后程序问你下标为2的位置的值,然后你输入2 ,然后程序问你下标为1的位置的值,你输入3 ,然后程序问你下标为4的位置的值,你输入4,然后程序问你下标为5的位置的值,你输入5,然后你输入5,最后程序返回一个局部最小值1的下标3

题解

  1. 之前也没怎么做过交互题,然后昨天晚上就没做出来,百度说交互题一般经验都是二分/三分找区间值,题中n是1e5,二分时间复杂度O(logn),找100次可以实现
  2. 题中要求找一个局部最小值,也就是找一个‘ V ’ 形的区间,那么中间值就是局部最小值,我们可以二分中间值mid,然后再询问一个mid+1 的值, 如果a[mid]>a[mid+1],说明这一部分单调递减,那么继续向右二分看是否还是单调递减,(因为右边边界是正无穷,所以一定存在递增区间) 以此来缩小区间,如果继续找是递增那么这个局部最小值就在这个区间,继续缩小区间,直到找到
  3. a[mid]<a[mid+1] 说明这个区间就是单调递增,因为左边界是正无穷,所以肯定有解,继续向左缩小区间,其余同上

代码

#include<bits/stdc++.h>

using namespace std;

int main() {

    int n, x, y;
    scanf("%d", &n);
    int l = 1, r = n;
    while (l < r) {
        int mid = (l + r) >> 1;
        printf("? %d\n", mid);
        fflush(stdout);
        scanf("%d", &x);
        printf("? %d\n", mid + 1);
        fflush(stdout);
        scanf("%d", &y);
        //说明这个区间单调递减,那么就要向右找一个单调递增的区间
        if (x > y) l = mid + 1;
        //这个区间单调递增,就要向左找一个单调递减的区间
        else r = mid;
    }
    printf("! %d", l);
    fflush(stdout);
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值