• 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.
  • 相关阅读:
    437. Path Sum III
    416. Partition Equal Subset Sum
    417. Pacific Atlantic Water Flow
    30.构建单机多容器环境-故障&31.构建单机多容器环境
    29.镜像容器与仓库
    【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总
    【笔记目录1】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总
    【笔记目录2】ASP.NET Core分布式项目实战
    【笔记目录1】ASP.NET Core分布式项目实战
    技术牛人感悟
  • 原文地址:https://www.cnblogs.com/Currier/p/6504452.html
Copyright © 2020-2023  润新知