P8664 [蓝桥杯 2018 省 A] 付账问题 题解
考虑目前已经考虑了 $i$ 个人,还需要付 $S'$ 元钱。
则剩下 $n-i+1$ 个人出的钱应该往他们的平均数 $\dfrac{S'}{n-i+1}$ 靠拢。
所以若第 $i+1$ 个人的钱数大于 $\dfrac{S'}{n-i+1}$,则他出 $\dfrac{S'}{n-i+1}$ 元钱,否则他出 $a_{i+1}$ 元钱(即他全部的钱)。
这样做的话未考虑的人的平均数单调不降,所以要尽量让钱多的人后考虑,贪心前把 $\{a_n\}$ 升序排序即可。
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int n, a[500050];
long double s, x, z, q;
int main()
{
scanf("%d%Lf", &n, &s);
x = 1.0 * s / n;
for (int i = 1; i <= n; ++i)
scanf("%d", a + i);
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; ++i)
z = min(1.0l * a[i], s / (n - i + 1.0)), q += (z - x) * (z - x), s -= z;
printf("%.4Lf", sqrt(q / n));
return 0;
}