提高组杂题训练

1.Another Array Problem

分类讨论。为了使和最大化,需要序列中的每个元素都为最大的元素。

\(n \ge 4\),设序列中的最大元素的位置为 \(x\) ,那么必有 $x-1 \ge 2 $ 或 \(n-x\ge2\) ,所以只需要选 \(n-1\)\(n\) 两个元素操作两次变为0,对\(x\sim n\) 赋值,再选 \(1\)\(2\) 两个元素操作两次变为0,对\(1\sim x-1\) 赋值

\(n=2\) ,两种情况。\(\left|a_i-b_i\right|\) 或不操作,取 \(\max\) 即可。

\(n=3\) ,若最大元素是 \(a_1\)\(a_3\) ,还是可以将每个元素都变成最大。若最大元素为\(a_2\),有两种情况。

若选择 \((1,2)\) 操作,每个数的最大值为 \(\max(a_3,\left|a_1-a_2\right|)\) ;若选择 \((2,3)\) 操作,每个数的最大值为 \(\max(a_1,\left|a_3-a_2\right|)\) ,最后取最大值即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,a[maxn],T,ans;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		if(n==1){
			cout<<a[1]<<'\n';
			continue;
		}
		else if(n==2){
			cout<<max(2*abs(a[1]-a[2]),a[1]+a[2])<<'\n';
			continue;
		}
		else if(n==3){
			cout<<max({3*abs(a[1]-a[2]),3*abs(a[3]-a[2]),3*a[1],3*a[3],a[1]+a[2]+a[3]})<<'\n';
			continue;
		}
		else{
			sort(a+1,a+1+n);
			cout<<a[n]*n<<'\n';
			continue;
		}
	}
}

2.The Human Equation

你说得对但是我最开始真的觉得很像贪心被硬控40min+

\(b\) 数组为 \(a\) 的前缀和,一次操作就是在 \(b\) 中任选一些数字 \(\pm1\)

手模一下发现 \(b\) 元素全0 是 \(a\) 元素全0 的充要条件。

求前缀和数组中的极值,相减即可。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+10;
int T,n,a[maxn];
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
		}
		for(int i=1;i<=n;i++) a[i]=a[i-1]+a[i];
		int mn=0,mx=0;
		for(int i=1;i<=n;i++) mn=min(mn,a[i]),mx=max(mx,a[i]);
		cout<<mx-mn<<'\n'; 
	}
}
posted @ 2024-12-01 19:37  Aapwp  阅读(10)  评论(0编辑  收藏  举报
我给你一个没有信仰的人的忠诚