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


    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好像是100w的……管他呢反正能A就行

    首先每个人最后肯定是得到金币平均数

    求一下每个人需要/多余的金币数量搞成前缀和再排序,然后取中位数乱搞

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define LL long long
    int a[1000010];
    LL s[1000010];
    LL tot,mid,sum;
    int n;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main()
    {
    	n=read();
    	for (int i=1;i<=n;i++)
    	{
    		a[i]=read();
    		tot+=a[i];
    	}
    	tot/=n;
    	for (int i=1;i<=n;i++)s[i]=s[i-1]+(a[i]-tot);
    	sort(s+1,s+n+1);
    	mid=s[(n+1)>>1];
    	for (int i=1;i<=n;i++)sum+=abs(mid-s[i]);
    	printf("%lld",sum);
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    浅谈Linux文件操作
    数据结构学习--队列
    CODE[VS] 1099 字串变换
    CODE[VS] 1026 逃跑的拉尔夫
    CODE[VS] 3027 线段覆盖 2
    LeetCode8.字符串转换整数(atoi) JavaScript
    JS实现继承 JavaScript
    LeetCode7.整数反转 JavaScript
    LeetCode6.Z字形变换 JavaScript
    LeetCode5.最长回文子串 JavaScript
  • 原文地址:https://www.cnblogs.com/zhber/p/4035923.html
Copyright © 2020-2023  润新知