• Spreading the Wealth,思维


    题目去洛谷

    题意:

      很清晰,n个人,每人有一些硬币硬币总数sum≡0(mod n),通过一些互相交换,使硬币数平均(即每人有相同个数的硬币)

    分析:

      还是有点思维含量的,我们这样想,我们其实就是要确定两两之间的硬币交换数量,设JHi表示第i个人和第i-1个人交换的硬币数量,特殊的JH1表示1和n交换的硬币的数量。其实我们只要确定了JH1,剩下的就都能确定了,我们先把交换的正负定义一下JHi为正表示i拿取,JHi为负表示i送出。

      我们设JH1=x,然后求出JH2:JH1+mo1-JH2=ba(ba表示这几个数的平均数)JH2=JH1+mo1-ba。我们找到每个的JHn=JH1-()n,于是,答案就是,sum(abs(JHi-x)),然后就是确定x,其实写到这大家就都看出来了找到中位数,然后就好了。想明白后其实挺简单的。

      补充:证明这样取JH1,JH2,JH3...不会卡住,如果卡住,那么给它的人一定要给他足够的,如果一个人两边给,就不会卡住,如果一直卡住,那么就有环,不成立。

    代码:

      

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int maxn=1000000+10;
    long long a[maxn];
    long long b[maxn];
    int main(){
        int n;
        while(~scanf("%d",&n)){
            long long sum=0;
            for(int i=1;i<=n;i++){
                scanf("%lld",&a[i]);
                sum+=a[i];
            }
            long long ba=sum/(long long)n;
            b[1]=0;
            for(int i=2;i<=n;i++)
                b[i]=b[i-1]+a[i-1]-ba;
            sort(b+1,b+1+n);//这么写可要想清楚,取了相反数。
            long long z=b[(n+1)/2];
            long long ans=0;
            for(int i=1;i<=n;i++)
                ans+=abs(b[i]-z);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    canvas粒子时钟
    数组复制
    对象拷贝
    不常见但很有用的chrome调试工具使用方法
    变形transform的副作用
    CSS页面渲染优化属性will-change
    CSS实现导航条Tab切换的三种方法
    CSS两端对齐
    CSS倒影
    CSS滤镜
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/12660194.html
Copyright © 2020-2023  润新知