bzoj3293[Cqoi2011]分金币

Posted Currier

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3293[Cqoi2011]分金币相关的知识,希望对你有一定的参考价值。

Description

圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等。你的任务是求出被转手的金币数量的最小值。

 

Input

第一行为整数nn>=3),以下n行每行一个正整数,按逆时针顺序给出每个人拥有的金币数。

 

 

Output

 

输出被转手金币数量的最小值。

Sample Input

4
1
2
5
4

Sample Output

4
样例解释
设四个人编号为1,2,3,4。第3个人给第2个人2个金币(变成1,4,3,4),第2个人和第4个人分别给第1个人1个金币。

HINT

N<=<=100000,总金币数<=10^9

 

 

可以发现只要确定了n给1的金币数,就可以确定所有人之间给的金币数,设n给1的金币数为x,写出总金币数关于x的函数,是一个绝对值函数,有几何意义,一个是一个初中就会的简单求最值,取中位数作为x就是最小值。

 1 program coin(input,output);
 2 var
 3   a,b:array[0..100010]of int64;
 4   n,i:longint;
 5   c,t,ans:int64;
 6 procedure sort(q,h:longint);
 7 var
 8   i,j:longint;
 9   x,t:int64;
10 begin
11    i:=q;j:=h;x:=b[(i+j)>>1];
12    repeat
13      while b[i]<x do inc(i);
14      while x<b[j] do dec(j);
15      if i<=j then
16         begin
17            t:=b[i];b[i]:=b[j];b[j]:=t;
18            inc(i);dec(j);
19         end;
20    until i>j;
21    if j>q then sort(q,j);
22    if i<h then sort(i,h);
23 end;
24 begin
25    assign(input,coin.in);assign(output,coin.out);reset(input);rewrite(output);
26    readln(n);
27    c:=0;
28    for i:=1 to n do begin readln(a[i]);c:=c+a[i]; end;
29    c:=c div n;
30    b[1]:=0;
31    for i:=2 to n do b[i]:=b[i-1]+c-a[i-1];
32    sort(1,n);
33    t:=b[(1+n)>>1];ans:=0;
34    for i:=1 to n do ans:=ans+abs(t-b[i]);
35    write(ans);
36    close(input);close(output);
37 end.

 

以上是关于bzoj3293[Cqoi2011]分金币的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ3293] [Cqoi2011] 分金币 (贪心)

bzoj1045: [HAOI2008] 糖果传递&&bzoj3293: [Cqoi2011]分金币

BZOJ-3293&1465&1045分金币&糖果传递×2 中位数 + 乱搞

bzoj P3293

P2512 [HAOI2008]糖果传递&&P3156 [CQOI2011]分金币&&P4016 负载平衡问题

bzoj3295: [Cqoi2011]动态逆序对