第一章例题3分金币UVa 11300(中位数)

11300 - Spreading the Wealth

Time limit: 6.000 seconds

 

F. Spreading the Wealth

Problem

A Communist regime is trying to redistribute wealth in a village.  They have have decided to sit everyone around a circular table.  First, everyone has converted all of their properties to coins of equal value, such that the total number of coins is divisible by the number  of people in the village.  Finally, each person gives a number of coins to the person on his right and a number coins to the person on his left, such that in the end, everyone has the same number of coins.  Given the number of coins of each person,  compute the minimum number of coins that must be transferred using this method so that everyone  has the same number of coins.

The Input

There is a number of inputs. Each input begins with n(n<1000001), the number of people in the village.n lines follow, giving the number of coins of each person in the village, in  counterclockwise order around the table.  The total number of coins will fit inside an unsigned 64 bit integer.

The Output

For each input, output the minimum number of coins that must be transferred on a single line.

Sample Input

3
100
100
100
4
1
2
5
4

Sample Output

0
4


 


Problem setter: Josh Bao

 

/*这是一道涉及到中位数的题,一上去谁也看不出这是中位数啊!
我们先分析一下这道题,由于要求最少的转手金币量,
那我们就要假设这n个人都是足够聪明的,什么叫足够聪明呢?
举个例子,1号给2号4个金币,2号又给1号3个金币,那你说这俩人不是有病吗,
直接1号给2号1个金币不就ok了吗
因此我们发现实际上两个人之间的金币给与不给只是单方向的,不会出现互相给。
由于是在一个圆环上,我们可以假设一个正方向,设x1是1给n的数量,x2是2给1的数量,。。。xn是n给n-1的数量
当然这些xi可正可负可为0的实际上。
我们知道什么条件呢?每个人初始的金币数a[i]和最终的金币数M
对于1,有a1+x2-x1=M,推出x2=x1+M-a1;
对于2,有a2+x3-x2=M,推出x3=x2+M-a2=x1+2M-a2-a1;
对于3,有a3+x4-x3=M,推出x4=x3+M-a3=x1+3M-a3-a2-a1;
........................................
对于n-1,有xn=x1+(n-1)M-a(n-1)-a(n-2)-...-a1;
对于n,这个式子是多余的
我们将上面的式子变为:
x2=x1-c1,x3=x1-c2;.........;xn=x1-c(n-1)
则我们要求的是|x1|+|x2|+|x3|+....+|xn|的最小值
也就是求|x1|+|x1-c1|+|x2-c2|+....+|x1-c(n-1)|的最小值
这实际上是中位数问题,当x1取0,c1,c2,...c(n-1)的中位数时最后的结果最小
序列cn的递推公式为cn=c(n-1)+an-M;
由于此题中c序列的下标是从0开始到n-1,则无论n为奇数还是偶数,
当x1取值为c[n/2]时最后的结果去的最小值
*/

#include
#include
#include
#include
using namespace std;
const int maxn=1000000+10;
long long int a[maxn];
long long int c[maxn];
int n;
int main()
{
 int i;
 while(cin>>n)
 {
  long long int tot=0;
  for(i=0;i   {
   scanf("%lld",&a[i]);
   tot+=a[i];
  }
  long long int M=tot/n;
  c[0]=0;
  for(i=1;i   {c[i]=c[i-1]+a[i]-M;}
  sort(c,c+n);
  long long int x1=c[n/2];
  long long int ans=0;
  for(i=0;i   {ans+=abs(x1-c[i]);}
  cout<  }
 return 0;
}

你可能感兴趣的:(ACM)