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号