题意:圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等。你的任务是求出被转手的金币数量的最小值。比如,n=4,且4个人的金币数量分别为1,2,5,4时,只需转移4枚金币(第3个人给第2个人两枚金币,第2个人和第4个人分别给第1个人1枚金币)即可实现每人手中的金币数目相等。(本段摘自《算法竞赛入门经典(训练指南)》)
分析:
可以将题目转化成求中位数来进行求解。
代码:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <string>
using namespace std;
const int maxn = 1000000 + 5, INF = 2000005;
int n;
long long c[maxn], a[maxn], sum, m, ans;
int main()
{
while (~scanf("%d", &n))
{
sum = 0;
ans = 0;
for (int i = 0; i < n; ++i)
{
scanf("%lld", &a[i]);
sum += a[i];
}
m = sum / n;
c[0] = 0;
for (int i = 1; i < n; ++i)
c[i] = c[i - 1] + a[i] - m;
sort(c, c + n);
for (int i = 0; i < n; ++i)
ans += abs(c[n / 2] - c[i]);
printf("%lld\n", ans);
}
return 0;
}