首页 > 其他分享 >蓝桥杯2018年A组-付账问题

蓝桥杯2018年A组-付账问题

时间:2024-04-08 21:56:12浏览次数:16  
标签:10 differ 样例 付账 蓝桥 标准差 2018 666 avg

0.题目

题目描述

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

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

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

标准差的介绍:标准差是多个数与它们平均数差值的平方平均数,一般用于刻画这些数之间的“偏差有多大”。形式化地说,设第 \(i\) 个人付的钱为 \(b_i\) 元,那么标准差为 \(s=\sqrt{\frac{1}{n}\sum_{i=1}^n(b_i-\frac{1}{n}\sum_{i=1}^n b_i)}\)

输入格式

第一行包含两个整数 \(n\)、\(S\);

第二行包含 \(n\) 个非负整数 \(a_1,\cdots,a_n\)。

输出格式

输出到标准输出。

输出最小的标准差,四舍五入保留 \(4\) 位小数。

保证正确答案在加上或减去 \(10^{-9}\) 后不会导致四舍五入的结果发生变化。

样例 #1

样例输入 #1

5 2333
666 666 666 666 666

样例输出 #1

0.0000

样例 #2

样例输入 #2

10 30
2 1 4 7 4 8 3 6 4 7

样例输出 #2

0.7928

提示

【样例解释】

  1. 每个人都出 2333/5 元,标准差为 0。

【数据约定】

对于 \(10\%\) 的数据,所有 \(a_i\) 相等;

对于 \(30\%\) 的数据,所有非 \(0\) 的 \(a_i\) 相等;

对于 \(60\%\) 的数据,\(n \le 1000\);

对于 \(80\%\) 的数据,\(n \le 10^5\);

对于所有数据,\(n \le 5 \times 10^5,0 \le a_i \le 10^9\)。

1.题解

1.1 贪心

思路

这里有很多需要注意的点:
1.这里我们首先明确一点:最终计算的avg是固定的,即 S / n
2.我们主要弄清一个问题:每个人付款有多有少,谁多谁少,如何让这个标准差最小
3.使用贪心的思路: 首先我们为了逼近avg:
3.0首先我们对于整个数组进行排序,便于后续使用贪心算法(这里sort排序,注意1.我a数组从下标1开始; 2.第二个参数是结束位置的下一个位置)
3.1如果存在有些钱不够的人(a[i] < avg),这些人两种选择:付全款/付部分; 如果他们付部分,他们自身首先和avg形成的标准差更大;其次对于后面有富裕的人,他们本来可
以用更接近avg的钱即可付完全款,但是由于你少付了,他们都要多付,跟avg的标准差也就更大;所以对于这部分人我们选择全部付款
3.2出现第二种人,有富裕,但不多(a[i] >= avg), 这些人能付的钱已经大于平均值,但是由于前面有人少付了钱,这时候我支付avg是不够的,需要他们进行多付.又回到了这
个问题,他们是全付还是付部分即可? 我们可以利用之前的遍历,更新剩余需支付的S,计算出新的平均值(总人数 n-i+1)avg', 对于剩余这部分的人,如果持钱最少的人都多
于avg',那么对于后面钱更多的人,也是能付起avg'的,而且这时候整体最逼近于avg(接近avg的都尽可能全付,直到出现一个符合的avg'),剩余部分的人只需要付avg'的钱款
即可.
4.这里判断 a[i] >= avg', 并不是写作 a[i] >= S' / (n - i + 1) 而是写作乘法,避免精度确实的问题!!!
5.注意最后所有人不是付款当前人持有的a[i], 而是均支付 avg' 即可, 由于持有钱款不是连续, 可能当前 a[i] > avg'!!!

代码

#include<bits/stdc++.h>
#define ll long long
const int M = 5e5 + 1;
ll a[M];
using namespace std;
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n;
	ll S;
	cin >> n >> S;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
	}

	sort(a+1, a+n+1);
	double avg = (S * 1.0) / n,  differ = 0;
	for(int i = 1; i <= n; i++) {
		// 钱够了,全部支付
		if (a[i] * (n - i + 1) >= S) {
			double remain_avg = S * 1.0 / (n-i+1);
			differ += (n - i + 1) * pow(remain_avg - avg, 2);
			break;
		} else {
			S -= a[i];
			differ += pow(a[i] - avg, 2);
		}
	}

	differ = sqrt(differ / n);
	printf("%.4lf", differ);
	return 0;
}

标签:10,differ,样例,付账,蓝桥,标准差,2018,666,avg
From: https://www.cnblogs.com/trmbh12/p/18122726

相关文章

  • 第十五届蓝桥杯第三期模拟赛 《台阶问题》
    问题描述小蓝要上一个楼梯,楼梯共有n级台阶(即小蓝总共要走n级)。小蓝每一步可以走a级、b级或c级台阶。请问小蓝总共有多少种方案能正好走到楼梯顶端?输入格式输入的第一行包含一个整数n。第二行包含三个整数a,b,c。输出格式输出一行包含一个整数,表示答案。答......
  • 第十四届蓝桥杯省赛研究生组python
    目录试题A:工作时长excel处理代码试题B:分糖果试题C:填充试题D:互质数的个数题解:暴力试题E:阶乘的和题解:暴力+备忘录试题F:公因数匹配题解:暴力试题G:小蓝的旅行计划题解试题A:工作时长excel处理把数据复制到excel,并选中列右键选择设置单元格格式注意:因为求和之后总小时数可能会超过2......
  • 蓝桥杯赛前突击
    蓝桥杯赛前突击1.大纲精读官方只支持Dev-cpp5.11(和平时用的差不多)。C++11的使用,在Dev-cpp工具里面选择编译选项输入-std=c++11并选择编译时加入以下命令。是支持使用unordered_map和auto的,还有__int128。一定要记得return0;去年听说是没return0;......
  • 蓝桥杯,推导部分和
    题意:给定若干个区间端点与区间和,还有若干个查询,求该查询的区间和。思路:带权并查集。总结:区间左端点-1是为了左开右闭(也可以右端点+1)。比如[1,2]=(0,2]=5,[3,4]=(2,4]=6。这样就得到了[1,4]=11(查询1可以直接得到代表元素4),处理边界情况更方便。可以思考一下,如果不......
  • 蓝桥杯2023年A组-试题D-平方差
    0.题目1.题解1.1基于中心扩展的字符串处理算法思路我们可以选定一个中心,然后从中心开始,向外扩展我们的子串,且能存储之前子串的部分性质(这里便于左等于右的情况)0.确定中心点这里我们用外层一个大循环来表示,中心点即为变量i。首先分为子串为奇数串和偶数串的情......
  • 【每周例题】蓝桥杯 C++ 对称排序
    对称排序题目对称排序 题目分析1.因为数字是对称交换,所以我们只需要判断前n/2项需不需要交换就好了2.这里我采用了升序排序,你们也可以尝试降序排序3.我们只需要排序好后再遍历一下整个数组,找出不符合排序的就输出NO就好了代码#include<iostream>#include<bits/stdc+......
  • 第十四届蓝桥杯单片机省赛
    第一部分客观题1.D2.BD3.CA时序逻辑电路是一类具有记忆功能且其输出不仅依赖于当前输入信号,还依赖于电路过去状态的数字电路。常见的时序逻辑电路包括但不限于以下几种类型:1.**触发器**:最基本的存储单元,如RS触发器、JK触发器、D触发器、T触发器等。2.**寄存器**:由多......
  • 蓝桥杯2023年A组-试题C-平方差
    0.题目1.题解1.1数学分析思路主要就是类似剪枝的思想,x必定满足某种条件,我们可以分奇偶情况进行讨论,最后在得出条件后使用暴力枚举.x=(y-z)(y+z)由于奇数±偶数=奇数,偶数±偶数=偶数,奇数±奇数=偶数;可以看出只要y,z的奇偶性质定了,则无论是加减奇......
  • P9231 [蓝桥杯 2023 省 A] 平方差
    因式分解之后发现,满足条件的x要么是奇数,要么是4的倍数#include<iostream>#include<stdio.h>#include<algorithm>#include<string>#include<cmath>#defineR(x)x=read()#defineFor(i,j,n)for(inti=j;i<=n;++i)usingnamespacestd;......
  • 蓝桥杯
    1.题目2.题解2.1贪心+堆思路由于如下图公式所示:要获取的是最大值(最坏情况),故如果increase增量小于零则没有必要讨论(存在刚开始由于b较大使得增量大于零,而k小于0,后面由于x增大导致增量为负值)可利用贪心局部最优(每次选择加人时,均是选择增量最大的一组),实现全......