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; }