传送门:洛谷 Make Equal | Codeforces B. Make Equal
更佳的阅读体验:CF1931B 题解
简要题意:有 $n$ 个水桶,每个水桶最初包含 $a_i$ 单位的水。可以从前面的水桶向后面的水桶倒水,求是否可以使所有桶里的水量相等。
首先应当求出每个水桶里最终会得到多少水。在输入时统计总的水量(即 $\sum a_i$),然后除以 $n$ 即可。
遍历整个序列,可以想到,如果当前水桶里的水比最终应该得到的水多,那么就可以把多的这部分倒出来;如果当前水桶里的水比最终应该得到的水少,那么就把先前倒出来的水倒进这个水桶里。
我们维护这个“倒出来的水”。如果这部分水变为负数,也就意味着出现了水不够用的情况。因此,如果“倒出来的水”在遍历整个序列的过程中一直保持非负,则表明这个序列合法。
#include <iostream>
using namespace std;
using ll = long long;
const int N = 2e5 + 10;
int t, n, a[N], diff; // diff 表示“倒出来的水”
ll aver; // 每个水桶分到的水
bool flag;
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
for (cin >> t; t; --t) {
aver = diff = 0, flag = false;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i], aver += a[i];
aver /= n;
for (int i = 1; i <= n; ++i) {
diff += a[i] - aver;
if (diff < 0) flag = true;
} cout << (flag ? "NO\n" : "YES\n");
} return 0;
}