zoukankan      html  css  js  c++  java
  • UVA 11300 分金币

    链接:https://uva.onlinejudge.org/index.php?///option=com_onlinejudge&Itemid=8&pa 
    ge=show_problem&problem=2275
    刚开始看到这题目,我是没什么想法的,没想到书上的技巧看起来如此的简单
    假设M为每个人都拥有的金币数,每个人的金币变化是左右相邻的人对其造成的影响
    假设这n个人构成一个环,先假设n=4,设x1指1号给4号多少金币,则x2代表2号给1号
    多少金币,其他的由此类推下去。
    则对于1号来说,他给了4号金币,则剩a1-x1
    2号给了他金币,则剩a1-x1+x2
    注意这里1号给4号和4号给1号的意义隐含在x1的符号里面(很巧妙),其他的类似
    由于最后要等于M,然后就可以得方程了
    a1-x1+x2=M >> x2 = x1-(a1-M) = x1 - C1
    a2-x2+x3=M >> x3 = x2-(a2-M)=x1-a1-a2-2*M = x1 - C2
    a3-x3+x4=M >> x4 = x3-a1-a2-a3-3*M = x1 - C3
    an-xn+x1=M >> xn = x1 - C(n-1)
    看到这里我们知道答案是所有xi的绝对值最小了
    很显然这就转化为数轴上求一点x到ci距离和的最小值,然而这个点x其实就是序列ci(排 
    序后)的中位数,稍微想想应该知道
    中位数可以用到许多此模型的题上
    看起来那么复杂,最后却如此简单,数学的强大力量
    代码如下:

     1 #include<cstdio>
     2 #include<math.h>
     3 #include<vector>
     4 #include<algorithm>
     5 #define LL long long
     6 using namespace std;
     7 
     8 const int maxn = 1e6+10;
     9 LL c[maxn];
    10 int main()
    11 {
    12     int n;
    13     LL a,sum,M;
    14     while(scanf("%d",&n)==1)
    15     {
    16         sum = 0;
    17         c[0] = 0;
    18         for(int i = 1; i<=n; i++)
    19         {
    20             scanf("%lld",&a);
    21             c[i] = c[i-1] + a;
    22             sum += a;
    23         }
    24         M = sum / n;
    25         for(int i = 1; i<n; i++) c[i] -= i*M;
    26         sort(c,c + n);
    27         LL x1 = c[n/2] , ans = 0;
    28         for(int i = 0; i<n; i++) ans += abs(x1-c[i]);
    29         printf("%lld
    ",ans);
    30 
    31     }
    32     return 0;
  • 相关阅读:
    Arduino Uno微控制器采用的是Atmel的ATmega328
    关于arduino与SPI
    fopen和fopen_s用法的比较
    C语言中 malloc
    补码原理——负数为什么要用补码表示
    晶振
    晶振(crystal)与谐振荡器(oscillator)
    LCD显示器缺陷自动化检测方案
    arduino 动态内存不足问题
    文档生成工具——Doxygen
  • 原文地址:https://www.cnblogs.com/jiachinzhao/p/4576012.html
Copyright © 2011-2022 走看看