1 条题解

  • 0
    @ 2026-5-5 8:16:32

    解题思路

    解法一:O(n2)O(n^2)

    枚举中间下标 jj,检查是否存在一个小于 aja_j 的元素在 jj 的左边,并且是否存在一个小于 aja_j 的元素在 jj 的右边。如果同时存在,则找到了一组合法的 (i,j,k)(i, j, k)

    解法二:O(n)O(n)(使用前缀/后缀最小值)

    可以通过预处理前缀最小值和后缀最小值来优化到 O(n)O(n)

    更巧妙的 O(n)O(n) 解法

    注意,如果存在答案,那么一定可以找到一个下标 jj,使得 aj1<aja_{j-1} < a_jaj>aj+1a_j > a_{j+1}(即一个“峰”)。
    因为如果不存在这样的连续三元组,这意味着排列是先严格递减到某个点,然后严格递增,此时不可能有 pi<pj>pkp_i < p_j > p_k 的结构。
    因此,我们只需要检查所有连续的三个元素 aj1,aj,aj+1a_{j-1}, a_j, a_{j+1} 是否满足 aj1<aj>aj+1a_{j-1} < a_j > a_{j+1} 即可。
    如果找到这样的 jj,则答案就是 (j1,j,j+1)(j-1, j, j+1);否则输出 NO


    C++ 代码实现(O(n)O(n) 解法)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int T;
        cin >> T;
        while (T--) {
            int n;
            cin >> n;
            vector<int> p(n);
            for (int i = 0; i < n; ++i) {
                cin >> p[i];
            }
    
            bool found = false;
            for (int j = 1; j < n - 1; ++j) {
                if (p[j - 1] < p[j] && p[j] > p[j + 1]) {
                    cout << "YES\n" << j << " " << j + 1 << " " << j + 2 << '\n';
                    found = true;
                    break;
                }
            }
            if (!found) {
                cout << "NO\n";
            }
        }
        return 0;
    }
    • 1

    信息

    ID
    6881
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者