您的位置:首页 > 其它

UVA 11300 Spreading the Wealth

2013-03-19 23:53 387 查看
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2275

UVA的题目

一道很好的数学题,与数据结构无关

把每一个人传递给上一个人的金币设为x[i],负数为逆传递

每人原有金币数位A[i]

ave为每人最终目的金币数

通过分析得知A[i]-x[i]+x[i+1] = sum/n ;

x
= x1 - (A1+A2+...+A[n-1] - (n-1) *ave)

用R
表示 上式后面括号部。

R
= R[n-1]+A[n-1] - ave

而所求值result = |x1|+|x2|+...+|xn| = abs(x1-R[0])+abs(x1-R[1])+abs(x1-R[2])+...+abs(x1-R[n-1])

令x1 = R[]的中值,则可以令result最小

特别要注意数据范围,读入的数据全部使用long long类型

#include <iostream>
#include <cstdio>
#include <algorithm>

#define N 10000200

using namespace std;

long long A
;
long long R
;

int main()
{
long long n;
while(scanf("%lld",&n)==1)
{
long long sum = 0;
for (int i=0;i<n;i++)
{
scanf("%lld",&A[i]);
sum+=A[i];
}
long long  ave = sum / n;

//x[i]设为第i个人要给上一个人的金币数,A[i]为原有金币
//x[1] = x1 - 0
//x[2] = x1 - (A1-ave)
//x[3] = x1 - (A1+A2-2*ave)
//x
= x1 - (A1+A2+...+A[n-1] - (n-1) *ave
//result = sum(x[1],x[2],...,x
)
//R[1] = 0;
//R[2] = A1-ave = R[1] + A[1] - ave;
//R[3] = A1+A2-2*ave = R[2] + A[2] -ave;
//...
//R
= R[n-1]+A[n-1] - ave
R[0] = 0;
for (int i=1;i<n;i++)
{
R[i] = R[i-1] + A[i-1] -ave;
}
sort(R,R+n);
long long x1 = R[n/2];
long long result = 0;
for (int i=0;i<n;i++)
{
result += abs(x1- R[i]) ;
}
printf("%lld\n",result);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: