您的位置:首页 > 其它

ZCMU-1019: 分金币

2017-08-07 22:33 169 查看

解题思路

这道题自己是真没想出来,但是参考了jnxxhzz同学的博客后,顺着思路进行数学分析,把这道题弄懂了。
具体数学分析参考http://blog.csdn.net/jnxxhzz/article/details/53191338
做算法的乐趣就是把实际问题转化成了数学问题,但是我还不具备这种思维,要加强学习。

Description

圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数相等。你的任务是求出被转手的金币数量的最小值。比如,n=4,且4个人的金币数分别为1,2,5,4时,只需转移4枚金币(第3个人给第2个人两枚金币,第2个人和第4个人分别给第1 个人1枚金币)即可实现每人手中的金币数目相等。

Input

输入包含多组数据。每组数据第一行为整数n(n<=1 000 000),以下n行每行为一个整数,按逆时针顺序给出每个人拥有的金币数。输入结束标志为文件结束符(EOF)。

Output

对于每组数据,输出被转手金币数量的最小值。输入保证这个值在64位无符号整数范围内。

Sample Input

3

100

100

100

4

1

2

5

4

Sample Output

0

4

我的解答

#include <stdio.h>
#include <stdlib.h>
long long a[1000001],b[1000001],m;
int cmp(const void *a,const void *b)
{
return *(int*)a-*(int*)b;
}
int main(void)
{
int n,i;
while(~scanf("%d",&n))
{
long long total=0;
for(i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
total+=a[i];
}
m=total/n;
b[0]=0;
for(i=1;i<n;i++)
b[i]=b[i-1]+a[i]-m;
qsort(b,n,sizeof(b[0]),cmp);
long long key=b[n/2];
long long sum=0;
for(i=0;i<n;i++)
sum+=labs(key-b[i]);
printf("%lld\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: