【题意】给你n个数,k个操作,每次操作把最大的减一,最小的加上一,直到最大的减一变成最小的,那么再把这个减掉的1加回去。
【分析&解题思路】orz队友!!!这题其实就是个赤果果的模拟呀。考虑求最大值的时候,我们考虑从右边切,求最小值的时候考虑从左边切。这样切出来之后,必然就是左边低右边高的情况合法。那么左边右边高呢,其实这里只用判断sum%n是否为0即可,如果为0值为0,否则为1。
【AC代码】
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define maxn 500010
int n,k,a[maxn];
ll sum;
int main(){
sum=0;
cin>>n>>k;
for(int i=0;i<n;i++) scanf("%d",&a[i]),sum+=a[i];
sort(a,a+n);
ll maxx=a[n-1],minn=a[0];
ll t=k;
//切,从右往左
for(int i=n-1;i>=0;i--){
if(maxx>a[i]){
ll temp = min(maxx-a[i],t/(n-i-1));
t-=temp*(n-i-1);
maxx-=temp;
}
}
//补,从左向右
t=k;
for(int i=0; i<n; i++){
if(minn<a[i]){
ll temp = min(a[i]-minn,t/i);
t-=temp*i;
minn+=temp;
}
}
//cout<<max(sum%n?1ll:0ll,maxx-minn)<<endl;
printf("%I64d\n",max(sum%n?1ll:0ll,maxx-minn));
return 0;
}