本文主要是介绍2018蓝桥杯C++A组——付账问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 问题描述
- 题目解析
- C++代码
- 结果
问题描述
【题目描述】
s = 1 n ∑ i = 1 n ( b i − 1 n ∑ i = 1 n b i ) 2 s=\sqrt{\frac{1}{n}\sum_{i=1}^{n}\left ( b_i-\frac{1}{n}\sum_{i=1}^{n}b_i \right )^2} s=n1i=1∑n(bi−n1i=1∑nbi)2
【输入】
【输出】
【样例输入】
5 2333
666 666 666 666 666
【样例输出】
0.0000
题目解析
我们可以简单分析一下,若能让每个人在够付账的情况下付的金额尽可能集中就可以使得标准差最小。
举个例子假如 n = 10 , S = 30 n=10,S=30 n=10,S=30,每个人金额分别为 1 , 2 , 3 , 4 , 4 , 4 , 6 , 7 , 7 , 8 1,2,3,4,4,4,6,7,7,8 1,2,3,4,4,4,6,7,7,8,先求出均值 a v g = 4.6 avg=4.6 avg=4.6,再对金额进行排序。
- 当金额小于均值时需要付出所有的钱;
- 当金额大于或等于均值时,这个人以及之后的所有人都需要在第一步完成的基础上重新计算均值即为 c u r _ a v g cur\_avg cur_avg
C++代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
LL S;
double ans,avg;void work()
{scanf("%d %lld",&n,&S);ans = 0.0;avg = 1.0*S/n; //总平均值LL *a = new LL[n]; //存储数据for(int i=0;i<n;i++)scanf("%lld",&a[i]);sort(a,a+n);for(int i=0;i<n;i++){if(a[i]*(n-i)<S) //比平均数小的话全额上缴{ans+=(a[i]-avg)*(a[i]-avg); //累加到方差上S-=a[i]; //已支付a[i],应支付额变小}else //当前及后续每个人的数额都超出当前值{double cur_avg = 1.0*S/(n-i); //算当前均值ans+=(avg-cur_avg)*(avg-cur_avg)*(n-i);break;}}printf("%.4lf\n",sqrt(ans/n));
}
int main()
{work();return 0;
}
结果
这篇关于2018蓝桥杯C++A组——付账问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!