求解代码:
#include <bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int a[N];
int main(){
long long n,S;
scanf("%lld%lld",&n,&S);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
double average=1.0*S/n;
double sum=0;
for(int i=0;i<n;i++){
if(a[i]*(n-i)<S){
sum+=(average-a[i])*(average-a[i]);
S-=a[i];
}else{
double current=1.0*S/(n-i);
sum+=(current-average)*(current-average)*(n-i);
break;
}
}
double ans=sqrt(sum/n);
printf("%.4lf\n",ans);
return 0;
}
解释:
标准差
标准差是衡量数据集合中数据间相似程度的一种度量,其计算方法为对所有数据求出其与平均值的差的平方,然后求出平均值,最后取这些平方值的平均数的平方根。
比如代码中的(average-a[i])*(average-a[i])与(current-average)*(current-average)是求平方后,除以n再开根号。
关键代码
//遍历每一个人
for(int i=0;i<n;i++){
if(a[i]*(n-i)<S){
sum+=(average-a[i])*(average-a[i]);
S-=a[i];
}else{
double current=1.0*S/(n-i);
sum+=(current-average)*(current-average)*(n-i);
break;
}
}
(1) 如果某个人所带的钱数 a[i] 乘以剩下的人数 (n-i) 小于总钱数 S,那么这个人应该付的钱数就是 a[i],将这个人对标准差的贡献累加到 sum 中。同时减去这个人所付的钱数 S -= a[i],继续处理下一个人。
(2) 如果某个人所带的钱数 a[i] 乘以剩下的人数 (n-i) 大于等于总钱数 S,那么这个人所应该付的钱数就应该是剩余的钱数 S / (n-i),将这个人对标准差的贡献累加到 sum 中,并且退出循环。、
这段值得多加思考