【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;
}
posted @ 2021-01-09 01:00  AWCXV  阅读(57)  评论(0编辑  收藏  举报