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

    题解:

    一道很经典的题目。

    用b[i]表示前i个人总共还需要多少金币(即第n人与第1人、第i人与下一个的金币交换情况)。

    设第n个人给了第1个人x金币,则第i个人与下一个人的金币流动量为|b[i]-x|。

    我们要使∑|b[i]-x|最小,则x应选b的中位数。

    代码(P++注意):

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define begin {
     4 #define end }
     5 #define while while(
     6 #define if if(
     7 #define do )
     8 #define then )
     9 #define for for(
    10 #define fillchar(a,b,c) memset(a,c,b)
    11 #define writeln printf("
    ")
    12 #define write printf
    13 #define readln readl()
    14 #define inc(a) a++
    15 #define dec(a) a--
    16 #define exit(a) return a
    17 #define mod %
    18 #define div /
    19 #define shl <<
    20 #define shr >>
    21 #define extended long double
    22 #define longint int
    23 #define integer short
    24 #define int64 long long
    25 template<typename T> inline void read(T& a)
    26 begin
    27   T x=0,f=1; char ch=getchar();
    28   while(ch<'0')or(ch>'9')do
    29   begin
    30     if ch=='-' then f=-1; ch=getchar();
    31   end
    32   while(ch>='0')and(ch<='9')do
    33   begin
    34     x=x*10+ch-'0'; ch=getchar();
    35   end
    36   a=x*f;
    37 end
    38 inline void readl()
    39 begin
    40   char ch; ch=getchar();
    41   while ch!='
    ' do ch=getchar();
    42 end
    43 int64 a[100001],b[100001];
    44 int64 tot,n,m,i;
    45 int64 ans;
    46 int main()
    47 begin
    48   read(n);
    49   for i=1;i<=n;i++ do begin read(a[i]); tot=tot+a[i]; end;
    50   tot=tot div n;
    51   for i=1;i<=n;i++ do b[i]=b[i-1]+tot-a[i];
    52   sort(b+1,b+n+1); tot=b[(1+n)div 2];
    53   for i=1;i<=n;i++ do ans=ans+abs(tot-b[i]);
    54   write("%lld",ans); writeln;
    55 end
    View Code
  • 相关阅读:
    onkeydown事件
    单击循环事件
    for-in循环
    in运算符
    数组成员升序降序排列
    bzoj 3754: Tree之最小方差树 模拟退火+随机三分
    bzoj 3752: Hack 预处理+暴力dfs
    hdu 5269 ZYB loves Xor I 分治 || Trie
    bzoj 4501: 旅行 01分数规划+概率期望dp
    bzoj 4260: REBXOR Trie+乱搞
  • 原文地址:https://www.cnblogs.com/GhostReach/p/6398346.html
Copyright © 2011-2022 走看看