CF1467B. Hills And Valleys
CF1467B. Hills And Valleys
描述
给你一个序列,包含 \(n\) 个整数 \(a_1,a_2,...,a_n\)。当 \(a_j>a_{j+1},a_j>a_{j-1}\) 时,我们称 \(j\) 为山峰,如果 \(a_j<a_{j+1},a_j<a_{j-1}\),我们称 \(j\) 为山谷,我们最多可以更改其中一个元素的值,问更改后,山峰和山谷个数的总和最少为多少。
思路
当我们更改 \(a_i\) 的值时,只有 \(a_{i-1},a_i,a_{i+1}\) 三个值会受到影响,考虑\(a_i\)的取值,再判断\(a_{i-1}\)和\(a_{i+1}\) 是山峰还是山谷即可。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int a[N];
int b[N];
int n;
bool is_hill(int i){
if(i>=2 && i<=n-1){
return a[i]>a[i-1] && a[i]>a[i+1];
}
return false;
}
bool is_valley(int i){
if(i>=2 && i<=n-1){
return a[i]<a[i-1] && a[i]<a[i+1];
}
return false;
}
int judge(int i){
return is_hill(i)||is_valley(i);
}
int main(){
int t; cin>>t; while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",a+i);
for(int i=1;i<=n;i++) b[i]=judge(i);
int delta_res=0;
for(int i=1;i<=n;i++){
int s=b[i];
if(i>=2) {
s+=b[i-1];
}
if(i<=n-1) {
s+=b[i+1];
}
int t=a[i];
int d=0;
if(i<=n-1) {
a[i]=a[i+1];
d=judge(i)+judge(i-1)+judge(i+1);
delta_res=min(delta_res,d-s);
}
if(i>=2){
a[i]=a[i-1];
d=judge(i)+judge(i-1)+judge(i+1);
delta_res=min(delta_res,d-s);
}
a[i]=t;
}
int sum=0;
for(int i=1;i<=n;i++) sum+=b[i];
cout<<sum+delta_res<<endl;
}
return 0;
}

浙公网安备 33010602011771号