代数推导
题意:将所有人的硬币进行一次平均分配,这里要注意的是,每个人只能和左右相邻的人交换硬币,而且这些人组成的是一个环
解法:
首先求出平均数为M
每个人初始的硬币为Ai
那么对于1,他能给予4号x1个硬币,并从2号出得到x2个硬币,那么对于1可得Ai-x1+x2 = M
同理可得An-xn+x1 = M
对上述的式子进行转化,可得
1:x2 =x1-C1 (C1 = A1 - M)
2:x3 = M-A2+x2 = 2M-A1-A2+x1 = x1-x2
…
最后所求为
|x1| + |x1-C1|+…+|x1-Cn-1|,要求这个最小,那么就是要x1为这些数的中位数
骚操作1
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<functional>
using namespace std;
#define swap(a,b) {long long c=a;a=b;b=c;}
const int MAX = 10e6+10;
const double Eps = 1e-12;
const double PI = acos(-1.0);
int gcd(int x, int y)
{
return x%y == 0 ? y : gcd(y, x%y);
}
long long a[MAX], c[MAX];
int main()
{
int t;
int k = 1;
while (cin>>t &&t)
{
int i, j;
vector<long long> v1,v2;
long long ave = 0;
for (i = 1; i <= t; i++)
{
cin >> a[i];
v1.push_back(a[i]);
ave += a[i];
}
ave /= t;
c[0] = 0;
v2.push_back(a[0]);
//cout << v1.front() << endl;
//cout << c[0] << endl;
for (i = 1; i < v1.size(); i++)
{
c[i] = c[i - 1] + a[i] - ave;
v2.push_back(c[i]);
}
sort(c, c + v1.size());
long long x1 = c[v1.size() / 2];
long long ans = 0;
for (i = 0; i < v2.size(); i++)
ans += abs(x1 - c[i]);
cout << ans << endl;
}
return 0;
}
骚操作2
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
#include<cctype>
#include<functional>
using namespace std;
#define swap(a,b) {long long c=a;a=b;b=c;}
const int MAX = 10e6+10;
const double Eps = 1e-12;
const double PI = acos(-1.0);
int gcd(int x, int y)
{
return x%y == 0 ? y : gcd(y, x%y);
}
int main()
{
int t;
int k = 1;
while (cin>>t &&t)
{
int i, j;
vector<long long> v1,v2;
long long ave = 0;
long long a, c;
for (i = 1; i <= t; i++)
{
cin >> a;
v1.push_back(a);
ave += a;
}
ave /= t;
//cout << v1.front() << endl;
//cout << c[0] << endl;
c = 0;
v2.push_back(c);
for (i = 1; i < v1.size(); i++)
{
c += v1[i] - ave;
v2.push_back(c);
}
//for (i = 0; i < v2.size(); i++)
// cout << v2[i] << endl;
//puts("***********");
sort(v2.begin(),v2.end());
//for (i = 0; i < v2.size(); i++)
// cout << v2[i] << endl;
long long x1 = v2[v1.size() / 2];
//cout << x1 << endl;
// puts("_________");
long long ans = 0;
for (i = 0; i < v2.size(); i++)
ans += abs(x1 - v2[i]);
cout << ans << endl;
}
return 0;
}