zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    javascript取最小值方法 apply
    c# 通过字符串获取与字符串同名的变量的值
    访问者地图 地址收藏
    自定义Dialog(一)
    android应用多主题
    maven setting 文件
    手动安装cloudera cdh4.2 hadoop + hbase + hive(三)
    手动安装cloudera cdh4.2 hadoop + hbase + hive(一)
    使用Hive读取Hbase中的数据
    手机共享电脑网络
  • 原文地址:https://www.cnblogs.com/Currier/p/6504452.html
Copyright © 2011-2022 走看看