# F. Honk's pool
# 题意
给定若干水池,每个水池有水升,每天按照下列顺序完成操作
- 从水最多的水池取一升水
- 往水最少的水池倒一升水
- 回家睡觉(到下一天)
问天以后最多水的水池与最少水的水池的差。
# 思路
排序,根据水池的水量离散化,维护一个有序数组,每个数组元素存
计算出天以后下界,用同样的方法计算上界,计算得结果。
要考虑到当天不到水量已经到达平均值的情况,在中间做好边界判断。
同时注意平均值可能不足以让所有水池都到达平均值,因此若所有水池都无法进行进一步操作时,水量差值可能为1。 根据余数可以判断这种情况。
# 代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iomanip>
#include <queue>
using namespace std;
using ll = long long;
const int maxn = 5e5 + 10;
int arr[maxn];
pair<int, int> pir[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, k;
while(cin >> n >> k) {
ll sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> arr[i];
sum += arr[i];
}
if (n == 1) {
cout << 0 << '\n';
return 0;
}
ll average = sum / n;
sort(arr + 1, arr + 1 + n);
int prev = -1, pos = 0;
for (int i = 1; i <= n; ++i) {
if (arr[i] != prev) {
prev = arr[i];
pir[++pos] = {arr[i], 1};
} else {
++pir[pos].second;
}
}
ll cur = 0;
int apos = 1;
bool finish = false;
for (int i = 1; i <= pos; ++i) {
if (pir[i].first >= average) {
cout << (sum % n ? 1 : 0) << '\n';
finish = true;
break;
}
apos = i;
ll increment = (ll)pir[i].second * (ll)abs(pir[i].first - min(pir[i + 1].first, (int) average));
if (cur + increment > k) {
break;
}
cur += increment;
pir[i + 1].second += pir[i].second;
}
if (finish) continue;
int lower = pir[apos].first + ((k - cur) / pir[apos].second);
int bpos = pos;
cur = 0;
for(int i = pos; i; --i) {
bpos = i;
ll decrement = (ll)pir[i].second * (ll)abs(pir[i].first - pir[i - 1].first);
if (cur + decrement > k) {
break;
}
cur += decrement;
pir[i - 1].second += pir[i].second;
}
int upper = pir[bpos].first - ((k - cur) / pir[bpos].second);
cout << upper - lower << '\n';
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74