AcWing 1235. 付账问题 贪心 均值不等式 细节决定成败

付账问题
在这里插入图片描述
在这里插入图片描述
输入样例1

5 2333
666 666 666 666 666

输出样例1

0.0000

输入样例2

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

输出样例2

0.7928

🤠 大佬神推理
⭐ 均值不等式 每个数的平方 的 平均数 >= 算术平均数的平方
在这里插入图片描述


⭐ 按 钱 升序排序(Arrays.sort() 默认按升序排序)
⭐ 带少的不够的话,带的钱全付,差额由后边的人平摊

👨‍🏫 运算精度问题,开 double ,减少运算次数
⭐ java printf 没有 lf
😡 数据范围(数组建议要多少开多少,除非卡栈空间)

import java.util.*;

public class Main
{
	static int N = (int) 5e5 + 10;
	static int[] a = new int[N];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		Long s = sc.nextLong();// 费用
		for (int i = 0; i < n; i++)
		{
			a[i] = sc.nextInt();
		}

//		注意类型转换
		double av = (double)s / n;// 平均值
		double cav = av;// 当前平均值,随着每个人付的费用而变化,也就是后边每个人需要平摊的费用
		double sum = 0;

		Arrays.sort(a, 0, n);

		for (int i = 0; i < n; i++)
		{
//			只要带的钱 <= 要均摊的费用,那就全付了,并计算方差
			if (a[i] <= cav)
			{
				s -= a[i];
				sum += (av - a[i]) * (av - a[i]);// 套方差公式
				cav = (double)s / (n - i - 1);
			} else
			{// 带多了的话,就只需要 付 当前平均值就好了
			//只要大于了,一次性把后面的都算完避免精度问题
				sum += (cav - av) * (cav - av)*(n-i);
				break;
			}
		}
		System.out.printf("%.4f\n", Math.sqrt(sum / n));

	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值