题目描述:环形排列的n(n<=106)(n<=106)个人,每人有一定量的金币。每个人可以给左右相邻的两个人金币,最终使得每个人都有相同量的金币。求被转手的最小金币数。
样例输入:
3
100
100
100
4
1
2
5
4
样例输出:
0
4
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define maxn 100000+10
long long a[maxn];
long long b[maxn];
long long c[maxn];
int n;
int main()
{
while (cin >> n)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
int sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum = sum + a[i];
}
int m = sum / n;
b[0] = 0;
for (int i = 1; i <= n-1; i++)
{
b[i] = b[i - 1] + a[i] - m;
}
sort(b,b + n);
long long x1 = b[n/2];
long long ans = 0;
for (int i = 0; i < n; i++)
{
ans = ans + abs(x1 - b[i]);
}
cout << ans << endl;
}
return 0;
}
基本思路,转化为几何问题,最后是首先要求出平均数M,每个人的硬币为numi;那么对于1,他能给予4号x1个硬币,并从2号出得到x2个硬币,那么对于1可得numi - x1 + x2 = M;
同理可得numn-xn+x1 = M。