bzoj3293 points gold

Topic Link

problem

N individual sitting on the round table, each person has a certain number of gold coins, the total number of coins is divisible by n. Each person can give about his neighbor who some gold coins, and finally to
have an equal number of coins of each person. Your task is to find the minimum number of coins being changed hands.

solution

There will certainly be no transfer between at least one position adjacent.
This enumeration position is assumed to be k. With x representing each person should have the final number of coins, \ (S_i \) represents the number before i personally owned and coins - before i individual should have the number of coins and. Then the first person i \ (i-1 \) be the number of coins that passed between individuals \ (| S_i-S_k | \) . Enumeration \ (S_k \) , statistics can answer.

code

/*
* @Author: wxyww
* @Date:   2019-12-14 19:29:29
* @Last Modified time: 2019-12-14 20:23:07
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 2000010;
ll read() {
    ll x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1; c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = x * 10 + c - '0'; c = getchar();
    }
    return x * f;
}
ll s[N],a[N];
int main() {
    int n = read();
    ll sum = 0;
    for(int i = 1;i <= n;++i) a[i] = read(),sum += a[i];

    ll x = sum / n;
    for(int i = 1;i <= n;++i) a[i] = a[i - 1] + a[i] - x;
    
    sort(a + 1,a + n + 1);

    for(int i = n;i >= 1;--i) s[i] = s[i + 1] + a[i];
    ll now = 0;
    ll ans = 1e16;
    for(int i = 1;i <= n;++i) {
        now += a[i];
        ans = min(ans,a[i] * i - now + s[i + 1] - a[i] * (n - i));
    }
    cout<<ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/wxyww/p/bzoj3293.html