题解:洛谷 AT_abc468_a Maximal Value

【题目来源】

洛谷:AT_abc468_a [ABC468A] Maximal Value

【题目描述】

给定一个长度为 \(N\) 的整数序列 \(A = (A_1, A_2, \ldots, A_N)\)

请计算有多少个整数 \(i\) 满足 \(1 \le i \le N-2\),并且 \(A_i < A_{i+1} > A_{i+2}\)

【输入】

输入从标准输入读入,格式如下:

\(N\ A_1\ A_2\ \ldots\ A_N\)

【输出】

输出满足条件的 \(i\) 的个数。

【输入样例】

6
3 1 4 1 5 2

【输出样例】

2

【核心思想】

  1. 问题分析:给定长度为 \(N\) 的序列 \(A\),统计满足 \(A_i < A_{i+1} > A_{i+2}\) 的索引 \(i\)\(1 \leq i \leq N-2\))的个数。这是一个线性扫描 + 局部峰值判定问题,核心在于识别序列中"先升后降"的局部极大值位置。

  2. 算法选择

    • 线性扫描:遍历 \(i\)\(1\)\(N-2\),直接检查三元组 \((A_i, A_{i+1}, A_{i+2})\) 是否满足 \(A_i < A_{i+1} > A_{i+2}\)
  3. 关键步骤

    • 读入数据:读取 \(N\) 和数组 \(A[1..N]\)
    • 遍历判定\(i\)\(1\)\(N-2\)):
      • \(A_i < A_{i+1}\)\(A_{i+1} > A_{i+2}\)\(ans \leftarrow ans + 1\)
    • 输出结果\(ans\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N)\),单次线性遍历
    • 空间复杂度:\(O(N)\),存储数组(可优化为 \(O(1)\) 滚动变量)
  5. 局部峰值判定的核心思想

    • 三元组模式识别\(A_i < A_{i+1} > A_{i+2}\) 描述了一个"先升后降"的局部极大值(峰)。遍历每个可能的起始索引 \(i\),检查中间元素 \(A_{i+1}\) 是否同时严格大于左右邻居
    • 严格不等式约束:题目使用严格小于和严格大于,因此相等的情况不计入。代码中的 >< 已满足严格性
    • 边界处理\(i\) 的范围为 \(1 \leq i \leq N-2\),确保 \(A_{i+2}\) 不越界。循环从 \(i=1\)\(i=N-2\) 即可覆盖所有合法三元组
    • 在线处理可能性:由于每次只用到当前三元组,可以用三个变量滚动存储,将空间优化到 \(O(1)\)
    • 适用于基础序列模式识别、局部特征统计类入门问题

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 105;  // 定义数组最大容量为105,满足N的数据范围
int n, ans;         // n为序列长度,ans记录满足条件的"峰"的个数
int a[N];           // a数组存储长度为N的整数序列

int main()
{
    cin >> n;       // 读入序列长度N
    for (int i = 1; i <= n; i++)  // 读入N个整数
        cin >> a[i];
    for (int i = 2; i < n; i++)  // 遍历序列中每个可能作为"峰"的位置(第2个到第n-1个元素)
        if (a[i] > a[i - 1] && a[i] > a[i + 1])  // 判断当前元素是否同时大于左右相邻元素(严格大于左边且严格大于右边)
            ans++;      // 找到一个满足A_{i-1} < A_i > A_{i+1}的"峰",计数加1
    cout << ans << endl;  // 输出满足条件的整数i的个数
    return 0;
}

【运行结果】

6
3 1 4 1 5 2
2
posted @ 2026-07-28 20:19  团爸讲算法  阅读(10)  评论(0)    收藏  举报