1.21练习

原题地址https://www.luogu.com.cn/problem/P4552
这道题是一道差分的题目,刚开始的时候我想的是找数列中的众数,然后求大于众数的数和小于众数的数与众数的最大差,然后再将它们相加,但这样很显然不对。在看了题解的思路后发现这道题其实不难(我太笨了)。
首先这道题是说通过选定区间[l,r],使得区间内的数加一或减一,让所有数相同。于是我们可以先求该数组的差分,即b[0]=a[0],b[i]=a[i]-a[i-1]。
可以得到如下代码:

点击查看代码
    vector <i64> b (n); //i64是我define的long long,这题不开long long会爆
    b[0]=a[0];
    for(int i=1;i<n;i++){
		b[i]=a[i]-a[i-1];	
    }

然后就是使得数组全部相等,即它们的差分数组除了第一个剩下的值全为0。我们可以设立两个值p,q。如果b[i]>0则p+=b[i];b[i]<0则q-=b[i],最终max(p,q)就是操作次数,abs(p-q)+1(最少有一种结果)就是可能的操作结果。
就是:

点击查看代码
for(int i=1;i<n;i++){
	int b[i]=a[i]-a[i-1];
	if(b[i]>0) p+=b[i];
	else q-=b[i];
}

代码可以简化,不必建立差分数组。
最终代码如下:

点击查看代码
#include <bits/stdc++.h>
#define i64 long long
using namespace std;
int main() {
    int n;
    cin>>n;
    vector <i64> a (n+1);
	unordered_map<int,int> count;
    for(int i=0;i<n;i++){
		cin>>a[i];
		count[a[i]]++;
	}
	i64 p=0,q=0;
//    vector <i64> b (n);
//    b[0]=a[0];
//    for(int i=1;i<n;i++){
//		b[i]=a[i]-a[i-1];	
//    }
	for(int i=1;i<n;i++){
		int b=a[i]-a[i-1];
		if(b>0) p+=b;
		else q-=b;
	}
	cout<<max(p,q)<<endl<<abs(p-q)+1<<endl;
    return 0;
}

posted @ 2025-01-21 16:50  扶风zer0  阅读(20)  评论(0)    收藏  举报