• [KOJ95603]全球奥运


    [COJ95603]全球奥运

    试题描述

    一个环形的图中有N个城市,奥运会重要项目就是传递圣火,每个城市有A[i]个圣火,每个城市可以向它相邻的城市传递圣火(其中1号城市可以传递圣火到N号城市或2号城市)。现在要传播最少的圣火来达到所有城市圣火数量一样。请输出这个最小的移动的圣火数量(比如说从1号城市要移动到N号城市M个圣火,那么ans加M)。

    输入

    第一行:一个数N,表示有N个城市。
    接下来N个整数,A[i]表示每个城市的圣火量。

    输出

    一个数:最少的圣火

    输入示例

    5
    15 7 11 3 14

    输出示例

    12

    数据规模及约定

    对于所有数据:N<=10^6,保证A[i]<=10^9。
    保证A[i]之和是N的倍数。

    题解

    显然最终状态肯定是每个城市手中圣火都是所有城市初始圣火的平均值。我们可以设 xi 表示第 i 个城市向第 i-1 个城市传递的圣火数量。那么假设第 i 个城市初始圣火为 Ai,则它最终圣火数量可以表示为 Ai - xi + xi+1 (i < n),或 An - xn + x1,那么我们可以想方设法将所有 xi (i > 1) 用 x1 表示,最终 ∑xi(0<i<n+1) = |x1| + |x1 - C1| + ... + |x1 - Cn-1| 得到这个形式之后,就可以令 x1 = 中位数 解决啦。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define maxn 1000010
    #define LL long long
    int n, A[maxn];
    LL sum, S[maxn];
    
    int main() {
    	n = read();
    	for(int i = 1; i <= n; i++) A[i] = read(), S[i] = S[i-1] + A[i], sum += A[i];
    	
    	sum /= n;
    	for(int i = 1; i <= n; i++) A[i] = S[i] - sum * i;
    	A[n] = 0;
    //	for(int i = 1; i <= n; i++) printf("%d ", A[i]); putchar('
    ');
    	sort(A + 1, A + n + 1);
    	int x = A[n+1>>1];
    	sum = 0;
    	for(int i = 1; i <= n; i++) sum += abs(x - A[i]);
    	
    	printf("%lld
    ", sum);
    	
    	return 0;
    }
    

    感觉这题总是忘啊,所以放一个详细的推式子的过程。。。

    A1 - x1 + x2 = S / n
    A2 - x2 + x3 = S / n
    A3 - x3 + x4 = S / n
    ...
    An - xn + x1 = S / n
    
    x2 - x1 = S / n - A1
    x3 - x2 = S / n - A2
    x4 - x3 = S / n - A3
    ...
    x1 - xn = S / n - An (We don't need this)
    
    x2 = S / n - A1 + x1
    x3 = S / n - A2 + x2 = S / n - A2 + S / n - A1 + x1 = x1 - ((A1 + A2) - 2(S / n))
    x4 = S / n - A3 + x3 = S / n - A3 + 2(S / n) - (A1 + A2) + x1 = x1 - ((A1 + A2 + A3) - 3(S / n))
    x5 = S / n - A4 + x4 = S / n - A4 + 3(S / n) - (A1 + A2 + A3) + x1 = x1 - ((A1 + A2 + A3 + A4) - 4(S / n))
    ...
    xi = x1 - ((A1 + A2 + A3 + ... + A(i-1)) - (i-1)(S / n))	(2 <= i <= n)
    /***********************************************************************************************
    	xn = (n-1)(S / n) - (A1 + A2 + A3 + ... + A(n-1)) + x1	(1)
    	xn = x1 - S / n + An					(2)
    	observe (1) and (2) and find that we don't need the last equation: x1 - xn = S / n - An
    ***********************************************************************************************/
    let Ci = (A1 + A2 + A3 + ... + A(i-1)) - (i-1)(S / n)		(2 <= i <= n)
    then xi = x1 - Ci
    sigma(|xi|) = sigma(|x1 - Ci|)
    
  • 相关阅读:
    很老的一篇文章:李翱(伊秀女性网):从程序员到精英站长的跨度
    推荐一款很好用的CSS下拉菜单框架
    网站推广之软文写作与发布技巧
    SEO网站外链接分析工具
    图解几大浏览器的区别(搞笑)
    好文摘抄:极简生活:一来,一去
    南通搜索引擎优化:浅谈国内SEO的发展趋势
    关注程序员健康之——程序员最有效的十大戒烟方法
    [你必须知道的css系列]第一回:丰富的利器:CSS选择符之通配符、类选择符、包含选择符、ID选择符
    [你必须知道的css系列]第一回:冠冕堂皇:CSS的作用及其基本结构
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5865780.html
Copyright © 2020-2023  润新知