【Codeforces Round #695 (Div. 2) B】Hills And Valleys

题目链接

链接

翻译

让你统计"山"和“山谷"的总个数,要求这个总个数最少。

你可以修改某个数字为任意整数。

题解

首先对于初始的数组,统计一下山加上山谷的总数(cnt)

然后枚举第 (i) 个位置,现在要对第 (i) 个位置上的数字进行修改了。

最直接的想法就是,改了 (a[i]) 之后,哪些位置上的山顶和山谷的值会受到影响呢?

只有 (i-1,i,i+1)(3) 个位置。

所以,在修改之前先减去这 (3) 个位置的影响,改了之后再加上影响用于更新最小值即可。

(a[i]) 的改法有 (5) 种情况(假设(a[i-1])(a[i+1]) 中较小值为 (xiao),较大值为 (da)

那么 (a[i]) 可以改为 xiao-1,xiao,xiao+1,da,da+1(5) 种情况,这样就能把 (a[i])(i-1)(i+1)

的影响都考虑到了。

然后 (cha) 的时候看了一下别人代码,好像有只需要改成 (a[i-1])(a[i+1]) 两者之一就可以的。。

代码

#include <bits/stdc++.h>
using namespace std;

const int N = 3e5;

int n,hills,valleys;
int a[N+10];

int calHill(int i){
    if (i == 1 || i == n){
        return 0;
    }
    if (a[i] > a[i-1] && a[i] > a[i+1]){
        return 1;
    }
    return 0;
}

int calValley(int i){
    if (i == 1 || i == n){
        return 0;
    }
    if (a[i-1] > a[i] && a[i] < a[i+1]){
        return 1;
    }
    return 0;
}

void sub(int i){
    for (int j = -1;j <= 1; j++){
        hills -= calHill(i+j);
        valleys -= calValley(i+j);
    }
}

void add(int i){
    for (int j = -1;j <= 1; j++){
        hills += calHill(i+j);
        valleys += calValley(i+j);
    }
}

int main(){
	#ifdef LOCAL_DEFINE
	    freopen("in.txt", "r", stdin);
	#endif
	ios::sync_with_stdio(0),cin.tie(0);
	int T;
	cin >> T;
	while (T--){
        cin >> n;
        hills = 0,valleys = 0;
        for (int i = 1;i <= n; i++){
            cin >> a[i];
        }
        for (int i = 2;i <= n-1;i++){
            hills += calHill(i);
            valleys += calValley(i);
        }
        int mi = hills + valleys;
        for (int i = 2;i <= n-1; i++){
            sub(i);
            int xiao = a[i-1],da = a[i+1];
            if (xiao > da){
                swap(xiao,da);
            }
            int temp = a[i];

            a[i] = xiao-1;
            if (a[i] < 1){
                a[i] = 1;
            }
            add(i);
            mi = min(mi,hills + valleys);
            sub(i);

            a[i] = xiao+1;
            if (a[i] > 1e9){
                a[i] = 1e9;
            }
            add(i);
            mi = min(mi,hills + valleys);
            sub(i);

            a[i] = da+1;
            if (a[i] > 1e9){
                a[i] = 1e9;
            }
            add(i);
            mi = min(mi,hills + valleys);
            sub(i);

            a[i] = xiao;
            add(i);
            mi = min(mi,hills + valleys);
            sub(i);

            a[i] = da;
            add(i);
            mi = min(mi,hills + valleys);
            sub(i);

            a[i] = temp;
            add(i);
        }
        cout << mi << endl;
	}
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/14253921.html