1 条题解

  • 0
    @ 2026-10-18 19:41:34

    标签:思维题 难度:中等

    题目大意

    有一排 (n) 个能量源,每个有一个权重 (a_i)。气团可以在任意位置生成,并向左或向右移动打通能量源。要求打通的顺序对应的权重序列必须是非递增的,求最少需要创建多少个气团。

    解题思路

    由于气团只能向左或向右单向移动,所以一段连续的单调序列(无论是递增还是递减)都只需要 1 团气就可以全部打通。

    什么时候需要增加新的气团呢?只有当遇到“波峰”的时候(即先上升后下降的转折点)。因为一团气无法同时覆盖波峰左侧下降的坡和右侧上升的坡,而其他能量源只要不在波峰就能被波峰的高位气打通,必须且只需在波峰处断开。

    所以,最少气团数 = 去重后数组中的“波峰”数量。

    具体实现技巧:

    1. 去重:相邻相同的元素合并,避免平坦区间对上升/下降趋势的判断产生干扰。
    2. 补边界:在去重后的数组首尾各补一个极小值(如 0,因为题目保证 (a_i > 0))。这样一来,哪怕波峰出现在最左端或最右端,也能统一被公式 a[i] > a[i-1] && a[i] > a[i+1] 判断出来。

    代码实现

    void solve() {
        int n;
        scanf("%d", &n);
        
        // 一边读入,一边去重 (下标从 1 开始存)
        int m = 0;
        for (int i = 0; i < n; i++) {
            int x;
            scanf("%d", &x);
            if (m == 0 || x != a[m]) {
                a[++m] = x; 
            }
        }
        
        // 首尾补 0,充当极小值边界
        a[0] = 0;
        a[m + 1] = 0;
        
        int ans = 0;
        // 直接找波峰:大于左右两边
        for (int i = 1; i <= m; i++) {
            if (a[i] > a[i - 1] && a[i] > a[i + 1]) {
                ans++;
            }
        }
        
        printf("%d\n", ans);
    }
    
    • 1

    信息

    ID
    1248
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    (无)
    递交数
    20
    已通过
    9
    上传者