题目链接https://codeforces.com/contest/1467/problem/B
思路:
其实在纸上模拟一下就知道,至少需要三个值才能形成凸起或凹陷的情况的,而这种情况的形成完全取决于第二个值,所以只需要将第二个值变为第一个值或第三个值(即a[i] = a[i -1], or a[i] = a[i + 1]),这种情况就会被缓解,我们只需要找到能缓解得最好的那种情况就行了。就遍历数组[1, n - 2]就行了(这里我数组下标是从0开始的)
以下是ac代码
#include <bits/stdc++.h>
using namespace std;
const int M = 3e5 + 10;
typedef long long ll;
int a[M];
int n;
int check(int i){
int res = 0;
if(i == 0 || i == n - 1) return 0;
if(a[i] > a[i - 1] && a[i] > a[i + 1]) res ++;
else if(a[i] < a[i - 1] && a[i] < a[i + 1]) res ++;
return res;
}
int main (){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t; cin >> t;
while(t --){
cin >> n;
int res = 0, sam = 0;
for(int i = 0; i < n; i ++) cin >> a[i];
for(int i = 1; i < n - 1; i ++){
if(a[i] > a[i - 1] && a[i] > a[i + 1]) res ++;
else if(a[i] < a[i - 1] && a[i] < a[i + 1]) res ++;
}
int Max = 0;
if(res <= 1) cout << 0 << "\n";
else {
for(int i = 1; i < n - 1; i ++){
int pre = check(i - 1) + check(i) + check(i + 1);
int temp = a[i];
a[i] = a[i - 1];
int now1 = check(i - 1) + check(i) + check(i + 1);
a[i] = a[i + 1];
int now2 = check(i - 1) + check(i) + check(i + 1);
a[i] = temp;
Max = max(Max, pre - min(now1, now2));
}
cout << max(res - Max, 0) << "\n";
}
}
return 0;
}