# ACwing 122. 糖果传递(数学 + 贪心)
题意
思路
假设\(n=4\),每个人的糖果数为\(a_1,a_2,a_3,a_4\),\(A_i\)表示第\(i\)个人给第\(i+1\)个人的糖果数(正表示给,负表示获得),那么可以表示成:
\(a_1 + A_4 - A_1 = ave \\ a_2 + A_1 - A_2 = ave \\ a_3 + A_2 - A_3 = ave \\ a_4 + A_3 - A_4 = ave\)
将\(A_i\)全部使用\(A_4\)表示:
\(A_1 = A_4 - (ave-a_1) \\ A_2 = A_4 - (2 * ave-(a_1+a_2)) \\ A_3 = A_4 - (3 * ave-(a_1 + a_2 + a_3) ) \\ A_4 = A_4 - 0\)
题目要求的就是求\(|A_1| + |A_2| + |A_3| + |A_4|\)的最小值,那么就可以理解为\((ave-a_1)\),\(2*ave-(a_1+a_2)\),\(3*ave - (a_1 + a_2 + a_3)\) , 0为数轴上的四个点,在数轴上选择一个点\(A_4\)使得这个点到其他点的距离之和最小,这就是典型的中位数问题了。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int a[maxn];
int n;
long long sum;
int main(){
cin>>n;
sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
long long ave=sum/n;
long long pre=0;
for(int i=0;i<n;i++){
pre+=a[i];
a[i]=ave*i-pre;
}
sort(a,a+n);
long long t=a[n/2];
long long ans=0;
for(int i=0;i<n;i++){
ans+=abs(a[i]-t);
}
cout<<ans<<endl;
return 0;
}