As we all know, Honk has n pools, numbered as 1 ~ n . There is ai liters water in the i-th pool. Every day, Honk will perform the following operations in sequence.
Please calculate the difference between the amount of water in the pool with the most water and the amount of water in the pool with the least water after the k days.
Input
The input consists of multiple test cases. The input is terminated by the end of file.The number of data sets will not exceed 40
The first line of each test case contains two integers n and k, which indicate the number of pools and the number of days to operate the pool.
The second line of each test case contains n integers, and the ii-th number represent ai indicating the initial amount of water in the i-th pool.
1≤n≤500000, 1≤k≤10^9, 1≤ai≤10^9.
Output
For each test case, print one line containing the answer described above.
样例输入
4 100
1 1 10 10
样例输出
1
样例输入
4 3
2 2 2 2
样例输出
0
https://nanti.jisuanke.com/t/41406
给你一个n数组,每次挑出最大的,令其减一,然后挑出最小的,令其加一。共操作 K 次,求最大值和最小值的差。
代码:
#include
using namespace std;
typedef long long ll;
multiset<ll>ste;
int main()
{
int n;ll k;
while(~scanf("%d%lld",&n,&k))
{
ste.clear();
for(int i=1;i<=n;++i)
{
ll a;
scanf("%lld",&a);
ste.insert(a);
}
multiset<ll>::iterator it1,it2;
while(k--)
{
it1=ste.begin();
ll a=*it1;
ste.erase(it1);
ste.insert(++a);
it2=--ste.end();
a=*it2;
ste.erase(it2);
ste.insert(--a);
}
ll ans=(*(--ste.end()))-(*ste.begin());
printf("%lld\n",ans);
}
return 0;
}
假设k特别大,那么最终的结果应该接近平均数,所以我们先求出平均数,然后分成两部分,左部分比平均数小,右部分比平均数大。然后分别对两部分进行二分,对右部分二分结果表示k次操作内可以使右部分内的最大值变到最接近平均数的值。对左部分二分结果表示k次操作内可以使左部分的最小值变到最接近平均数的值。然后我们可以右部分的结果-左部分的结果就是我们要求的结果。
代码:
#include
using namespace std;
typedef long long ll;
int a[500000+50];
int n, k;
bool check(int mid, bool flag)
{
ll sum = 0;
for(int i = 1; i <= n; i++) {
if(flag && a[i] > mid)
sum += a[i] - mid;
else if(!flag && a[i] < mid)
sum += mid - a[i];
}
if(k >= sum) {
return true;
}
else
return false;
}
int main()
{
while(~scanf("%d%d", &n, &k)) {
ll sum = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
sum += (ll)a[i];
}
int ave;
if(sum % n == 0)
ave = sum / n;
else
ave = sum / n + 1;
sort(a+1, a+n+1);
int l = ave, r = a[n];
while(l < r) {
int mid = l + r >> 1;
if(check(mid, true)) {
r = mid;
} else
l = mid + 1;
}
int ans1 = r;
l = a[1], r = ave;
if(sum % n)
r--;
while(l < r) {
int mid = l + r + 1 >> 1;
if(check(mid, false)) {
l = mid;
} else
r = mid - 1;
}
int ans2 = l;
cout << ans1 - ans2 << endl;
}
return 0;
}