zoukankan      html  css  js  c++  java
  • BZOJ3293: [Cqoi2011]分金币(数学)

    3293: [Cqoi2011]分金币

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1596  Solved: 969
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行为整数n(n>=3),以下n行每行一个正整数,按逆时针顺序给出每个人拥有的金币数。
    3<=N<=100000,总金币数<=10^9

    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

    Source

    思路:高中数学就讲过了,构造关于第一位的方程,可以得到每个数应该移动多少个,由于是代价,我们要加绝对值,然后是一个绝对值公式,取中位数时有最小值。 这里用nth_element来得到中位数。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=1000010;
    int a[maxn],d[maxn]; ll av,ans;
    void read(int &x){
        x=0; char c=getchar();
        while(c>'9'||c<'0') c=getchar();
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    }
    int main()
    {
        int N; scanf("%d",&N);
        rep(i,1,N) read(a[i]),av+=a[i]; av/=N;
        rep(i,2,N) d[i]=d[i-1]+av-a[i];
        nth_element(d+1,d+(N+1)/2,d+N+1);
        int num=d[(N+1)/2];
        rep(i,1,N) ans+=abs(d[i]-num);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    指针和数组分析(上)
    函数对象分析
    C语言关键字
    STM32串口遇到的一个问题
    map文件分析
    对象的销毁
    对象的构造顺序
    JavaScript实现表单的校验以及匹配正则表达式
    Python Turtle库绘制表盘时钟
    Python Turtle库绘制蟒蛇
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9995658.html
Copyright © 2011-2022 走看看