zoukankan      html  css  js  c++  java
  • L Spreading the Wealth----中位数法

    题目

    A Communist regime is trying to redistribute wealth in a village. They have have decided to sit everyone
    around a circular table. First, everyone has converted all of their properties to coins of equal value,
    such that the total number of coins is divisible by the number of people in the village. Finally, each
    person gives a number of coins to the person on his right and a number coins to the person on his left,
    such that in the end, everyone has the same number of coins. Given the number of coins of each person,
    compute the minimum number of coins that must be transferred using this method so that everyone
    has the same number of coins.

    Input

    There is a number of inputs. Each input begins with (n (n < 1000001)), the number of people in the
    village. (n) lines follow, giving the number of coins of each person in the village, in counterclockwise
    order around the table. The total number of coins will fit inside an unsigned 64 bit integer.

    Output

    For each input, output the minimum number of coins that must be transferred on a single line.

    题意翻译

    题目描述

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

    输入格式

    输入包含多组数据。每组数据第一行为一个整数(n(n<=1000000)n(n<=1000000)),以下n行每行为一个整数,按逆时针顺序给出每个人拥有的金币数。输入结束标志为文件结束符((EOF)).

    输出格式

    对于每组数据,输出被转手的金币的数量的最小值。输入保证这个值在(64)位无符号整数的范围之内。

    Sample Input

    3
    100
    100
    100
    4
    1
    2
    5
    4
    

    Sample Output

    0
    4
    

    题解

    解题思路

    这道题和均分纸牌类似

    (s(i))表示前(i)个人需要给别人或要来的硬币数之和

    求中位数,可得最优方案

    long long !!

    代码

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #define int long long
    using namespace std;
    const int N = 1e6+5;
    int n, a[N], s[N], b, ans;
    signed main() {
    	//freopen("1.in", "r", stdin);
    	while (scanf("%lld", &n) == 1) {
    		b = ans = 0;
    		for(int i = 1; i <= n; i++)
    			scanf("%lld", &a[i]), b += a[i];
    		b /= n;
    		for(int i = 1; i <= n; i++)
    			s[i] = s[i-1] + a[i] - b;
    		sort(s+1, s+n+1);
    		for(int i = 1; i <= n; i++)
    			ans += abs(s[i] - s[n/2]);
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }	
    
  • 相关阅读:
    乘法DAC一点知识
    #4 判断字符串是否为整数
    #3 不使用循环输出1到100
    #2 判断一个字符串是否包含重复字符
    #22 结语
    #1 组成互不相同且不重复的三位数
    #21 Python异常
    #19 re&jieba模块
    2020国庆正睿笔记
    2019正睿csp-s赛前冲刺
  • 原文地址:https://www.cnblogs.com/Z8875/p/12662903.html
Copyright © 2011-2022 走看看