Spreading the Wealth,思维

题目去洛谷

题意:

  很清晰,n个人,每人有一些硬币硬币总数sum≡0(mad 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,其实写到这大家就都看出来了找到中位数,然后就好了。想明白后其实挺简单的。

代码:

  

#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\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wish-all-ac/p/12660194.html
今日推荐