原题地址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;
}