uva11300 分金币(中位数)
来源:https://vjudge.net/problem/UVA-11300
题意:
有n个人围成一圈,每个人有一定数量的金币,每次只能挪动一个位置,求挪动的最少金币使他们平分金币
题解:
蓝书p6
令x1为1号给2号的金币数,负数代表反方向 x2为2号给3号的金币数 x3为3号给4号的金币数
而a1-x1+xn=m(m为平均数)a2-x2+x1=m a3-x3+x2=m
我们要求的就是|x1|+|x2|+|x3|+...|xn|
用x1表示x2,x3,x4
ans=|x1|+|x1-G1|+|x1-G2|....
x1到n个点的距离和最短时,就是正解
而这个点==G[MID]
#include <cstdio> #include <algorithm> #include <iostream> #define ll long long using namespace std; const int maxn=1000000+5; ll num[maxn]; int main() { int n; while(scanf("%d",&n)!=EOF) { ll sum=0; for(int i=1;i<=n;i++) { scanf("%lld",&num[i]); sum+=num[i]; } ll M=sum/n; num[1]=0; for(int i=2;i<=n;i++) num[i]=M-num[i]+num[i-1]; sort(num+1,num+1+n); int mid=n/2+1; ll ans=0; for(int i=1;i<=n;i++) ans+=abs(num[mid]-num[i]); printf("%lld\n",ans); } return 0; }