zoukankan      html  css  js  c++  java
  • [CF1479A/CF1480C] Searching Local Minimum

    [CF1479A] Searching Local Minimum - 二分

    Description

    藏一个排列,(n le 10^5),最多 100 次询问,找到任意一个局部最小值 (a_i<a_{i+1},a_i<a_{i-1})

    Solution

    先把一些容易判的判掉,比如 (nle 100)(a_1,a_n) 之类

    类似二分,维护两个端点,每次取中间,看中间这个位置的相邻三个元素是什么大小关系

    如果中间最小,运气太好,那么已经找到答案,直接结束

    如果中间最大,随便往哪边走

    如果是单调的,那么往有减小趋势的那边走

    (并不会证明)

    #include <bits/stdc++.h>
    using namespace std;
    
    int ask(int i)
    {
        cout << "? " << i << endl;
        cout.flush();
        int x;
        cin >> x;
        return x;
    }
    
    void finish(int x)
    {
        cout << "! " << x << endl;
        cout.flush();
        exit(0);
    }
    
    const int N = 100005;
    int n, a[N];
    
    void test(int x)
    {
        if (x == 1 || x == n)
            return;
        int mid = x;
        int xl = ask(mid - 1), xm = ask(mid), xr = ask(mid + 1);
        if (xl > xm && xm < xr)
            finish(mid);
    }
    
    signed main()
    {
        cin >> n;
    
        if (n == 1)
        {
            finish(1);
        }
        if (n <= 100)
        {
            for (int i = 1; i <= n; i++)
                a[i] = ask(i);
            finish(min_element(a + 1, a + n + 1) - a);
        }
        a[1] = ask(1);
        a[2] = ask(2);
        a[n - 1] = ask(n - 1);
        a[n] = ask(n);
        if (a[1] < a[2])
            finish(1);
        if (a[n - 1] > a[n])
            finish(n);
        int l = 1, r = n;
        while (r - l > 3)
        {
            int mid = (l + r) / 2;
            int xl = ask(mid - 1), xm = ask(mid), xr = ask(mid + 1);
            if (xl > xm && xm < xr)
                finish(mid);
            if (xl < xm && xm < xr)
                r = mid;
            else if (xl > xm && xm > xr)
                l = mid;
            else
                r = mid;
        }
        for (int i = l; i <= r; i++)
            test(i);
        throw("...");
    }
    
  • 相关阅读:
    vim字符串替换命令
    Android中View的事件分发机制——Android开发艺术探索笔记
    jQuery源代码框架思路
    C指针——C语言手记
    Python基础二--基本控制语句
    C++中的链式操作
    求一个字串中最长的连续字符串
    C# -- 推断字符能否转化为整形
    Loadrunner检查点使用总结
    LoadRunner设置检查点的几种方法介绍
  • 原文地址:https://www.cnblogs.com/mollnn/p/14387524.html
Copyright © 2011-2022 走看看