Description
有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
Input
第一行一个正整数n<=987654321,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的
糖果的颗数.
Output
求使所有人获得均等糖果的最小代价。
Sample Input
4
1
2
5
4
1
2
5
4
Sample Output
4
HINT
Source
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~结论题~
设每个人刚开始有a[i],给出b[i],c[i]=a[i]-tot的前缀和,最终成为tot个,那么
a[1]-b[1]+b[2]=tot;
a[2]-b[2]+b[3]=tot;
……
化简得
b[2]=tot-a[1]+b[1]=b[1]-c[1];
b[3]=tot-a[2]+b[2]=b[1]-c[2];
……
所以所求就相当于是数轴上距离所有点的距离总和最小的点,是所有点的中位数。
注意开long long!
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
int n,a[1000001],c[1000001];
ll tot,ans;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();tot+=a[i];
}
tot/=n;
for(int i=1;i<=n;i++) c[i]=c[i-1]+a[i]-tot;
sort(c+1,c+n+1);
tot=c[(n>>1)+1];
for(int i=1;i<=n;i++) ans+=abs(c[i]-tot);
printf("%lld\n",ans);
return 0;
}