Codeforces Round #352 (Div. 2) D. Robin Hood (二分法+判断平衡态)

解题思路: 由求最小值和求最大值各自二分。

由l*(a[l+1]-a[l]):求取填 1~l 到a[l+1]的高度需要多少的钱,如果大于剩余的k 则可执行 若否 判断剩余的k是否为l,若否最小值为a[l],否则 为a[l]+k/l;

由(n-r+1)*(a[r]-a[r-1]):求去掉n~n-r+1的这部分需要多少钱,如果大于剩余的k 则执行 若否 判断剩余的k是否为n-r+1,若是最大值为a[n-r+1]-k/(n-r+1);

如果最大值小于最大值,直接printf

如果最小值大于等于最大值,证明计算经过了平衡态,因为富人变穷会得到金币,所以会得到一个稳定状态;

当为sum(金币总和)刚好为n的倍数时,金币相差为0,若否金币相差为1;

 

#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;

int a[500100];
int n,k;
ll sum;

int main(){
    scanf("%d%d",&n,&k);
    
    sum=0;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
    
    sort(a+1,a+n+1);
    
    int l=1,r=n;
    int t[2]={k,k};
    while(t[0]&&l<n){
        if(t[0]>=1LL*l*(a[l+1]-a[l])) t[0]-=1LL*l*(a[l+1]-a[l]),l++;
        else break;
    }
    
    while(t[1]&&r>1){
        if(t[1]>=1LL*(n-r+1)*(a[r]-a[r-1])) t[1]-=1LL*(n-r+1)*(a[r]-a[r-1]),r--;
        else break;
    }
    
    int judge[2]={a[l]+t[0]/l,a[r]-t[1]/(n-r+1)};
    
    if(judge[0]<judge[1]){
        printf("%d\n",judge[1]-judge[0]);
    }else printf("%d\n",(int)(sum%n!=0));
    
    return 0;
} 

 

posted @ 2016-05-14 00:28  FireCool  阅读(187)  评论(0编辑  收藏  举报