首页 > 技术文章 > 蓝桥杯2018-省赛-C/C++-A组10题

memocean 2020-02-11 12:20 原文

题目
标题:付账问题

【题目描述】
几个人一起出去吃饭是常有的事。但在结帐的时候,常常会出现一些争执。

现在有 n 个人出去吃饭,他们总共消费了 S 元。其中第 i 个人带了 ai 元。幸运的是,所有人带的钱的总数是足够付账的,但现在问题来了:每个人分别要出多少钱呢?

为了公平起见,我们希望在总付钱量恰好为 S 的前提下,最后每个人付的钱的标准差最小。这里我们约定,每个人支付的钱数可以是任意非负实数,即可以不是1分钱的整数倍。你需要输出最小的标准差是多少。

标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的“偏差有多大”。形式化地说,设第 i 个人付的钱为 bi 元,那么标准差为 : [参见p1.png]

【输入格式】
从标准输入读入数据。

第一行包含两个整数 n、S;
第二行包含 n 个非负整数 a1, ..., an。

【输出格式】
输出到标准输出。

输出最小的标准差,四舍五入保留 4 位小数。
保证正确答案在加上或减去 10^−9 后不会导致四舍五入的结果发生变化。

【样例1输入】
5 2333
666 666 666 666 666

【样例输出】
0.0000

【样例解释】
每个人都出 2333/5 元,标准差为 0。

再比如:
【样例输入】
10 30
2 1 4 7 4 8 3 6 4 7

【样例输出】
0.7928

【数据说明】
对于 10% 的数据,所有 ai 相等;
对于 30% 的数据,所有非 0 的 ai 相等;
对于 60% 的数据,n ≤ 1000;
对于 80% 的数据,n ≤ 10^5;
对于所有数据,n ≤ 5 × 10^5, 0 ≤ ai ≤ 10^9。


资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms


请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。

提交程序时,注意选择所期望的语言类型和编译器类型。

代码

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstdio>
 5 using namespace std;
 6 int main(){
 7     int n;
 8     double S;
 9     cin>>n>>S;
10     int a[n];
11     for(int i=0;i<n;i++){
12         cin>>a[i];
13     }
14     double deficiency=0;//缺失的金额 
15     double ave=S/n;
16     double ans=0;
17     sort(a,a+n);//从小到大排序 
18     for(int i=0;i<n;i++){
19         if(a[i]<=ave){//均值之前,能出多少出多少,统计缺失的总值deficiency 
20             ans+=(ave-a[i])*(ave-a[i]);
21             deficiency+=(ave-a[i]); 
22         }else{
23             double reave=deficiency/(n-i);//计算后面的人需要均摊的多付的钱reave 
24             if(a[i]<ave+reave){//带的钱不够ave+reave的 
25                 ans+=(a[i]-ave)*(a[i]-ave);
26                 deficiency-=(a[i]-ave);
27             }else{//够ave+reave的 
28                 ans+=reave*reave;
29                 deficiency-=reave;
30             }
31         } 
32     }
33     printf("%.4f",sqrt(ans/n));
34 } 

 

推荐阅读