CF 1467 B. Hills And Valleys

B. Hills And Valleys(思维,模拟)

在这里插入图片描述

一道水题,但是没做出来,仔细想想是自己想的不全。
改一个数,让新的序列的谷和峰最少。遍历1到n的所有位置,将初始威胁记录下来,改变位于i的位置的大小。
改变大小的方法无非就是以下5种情况:
1.a[i]改成a[i - 1]和a[i + 1]中的最小值。
2.a[i]改成a[i - 1]和a[i + 1]中的最大值。
3.a[i]改成比a[i - 1]和a[i + 1]小。
4.a[i]改成比a[i - 1]和a[i + 1]大。
5.a[i]改成在a[i - 1]和a[i + 1]之间。
将改变之后的威胁记录下来,记录最小值。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 10;
#define int long long
int t, n, a[maxn];
int judge(int i) {
    
    
    if (i >= 2 && i <= n - 1) {
    
    
        if (a[i] > a[i + 1] && a[i] > a[i - 1]) return 1;
        if (a[i] < a[i + 1] && a[i] < a[i - 1]) return 1;
    }
    return 0;
}
signed main() {
    
    
    cin >> t;
    while (t--) {
    
    
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
        int ans = 0, temp = 0;
        for (int i = 2; i <= n - 1; i++)
            if (judge(i)) ans++;
        for (int i = 1; i <= n; i++) {
    
    
            int now = judge(i - 1) + judge(i + 1) + judge(i), last = 1e9, f = a[i];
            a[i] = min(a[i - 1], a[i + 1]) - 1;  //比小的小
            last = min(last, judge(i - 1) + judge(i + 1) + judge(i));
            a[i] = max(a[i - 1], a[i + 1]) + 1;  //比大的大
            last = min(last, judge(i - 1) + judge(i + 1) + judge(i));
            a[i] = min(a[i - 1], a[i + 1]) + 1;  //位于中间
            last = min(last, judge(i - 1) + judge(i + 1) + judge(i));
            a[i] = a[i - 1];  //相等
            last = min(last, judge(i - 1) + judge(i + 1) + judge(i));
            a[i] = a[i + 1];  //相等
            last = min(last, judge(i - 1) + judge(i + 1) + judge(i));
            temp = max(temp, now - last);
            a[i] = f;
        }
        cout << ans - temp << endl;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_47783181/article/details/112987209