10块钱怎么较为平均分给三个人

背景

隔壁王老师遇到了一个问题,学校给了10元钱,需要平均分给张三,李四和王五3人。王老师犯难了。

方案1

张三说,那好办,10 / 3 = 3.33333… 王老师每个人给3.34元那不就好了吗?王老师说,不行呀! 3.34*3 = 10.02 我不是亏了。要不我每个人给3.33元可不可以。 张三坚决不同意,反手举报王老师贪污他们的0.01元。

方案2

聪明的李四说了,要不这样,你先随机打算顺序,前2位给 3.33 元,最后一位给 10 - 3.33 * 2 = 3.34 元。这样就不存在谁亏了的说法。

实现
function equallyMoney($money, $weightMap) : array
{
     // 这边为了让结果比较公平 应该需要加一步随机 具体按照业务逻辑修改
    $totalWeight = array_sum($weightMap);  // 这里的权重为整数 如果有小数。需要用高精度加法
    $res = [];
    foreach ($weightMap as $key => $weight) {
        $res[$key] = bcdiv(bcmul($money, $weight, 2), $totalWeight, 2);
        $money = bcsub($money, $res[$key], 2);
        $totalWeight = bcsub($totalWeight, $weight, 4);
    }
    return $res;
}
运行结果
echo json_encode(equallyMoney(10, ['张三' => 1, '李四' => 1, '王五' => 1]), JSON_UNESCAPED_UNICODE);

{"张三":"3.33","李四":"3.33","王五":"3.34"} // 共10

王五运气比较好,而且大家相差不大,于是大家散了。

方案3

第二天学校又给了王老师20元钱,要发给张三,李四,王五,赵六,孙七和周八,王老师又拿出原来的算法

运行结果
echo json_encode(equallyMoney(20, ['张三' => 3, '李四' => 3, '王五' => 3, '赵六' => 3, '孙七' => 3, '周八' => 3]), JSON_UNESCAPED_UNICODE);

{"张三":"3.33","李四":"3.33","王五":"3.33","赵六":"3.33","孙七":"3.33","周八":"3.35"} // 共20

王五不同意了,为啥我们都是3.33 周八却有 3.35他算什么√8 我不同意。王老师听了三天睡不着觉,于是又了以下算法。

实现
// 这边具体实现中加了权重字段
public static function equallyMoney($money, $weightMap) : array
{
     // 这边为了让结果比较公平 应该需要加一步随机 具体按照业务逻辑修改
    $totalWeight = array_sum($weightMap);  // 这里的权重为整数 如果有小数。需要用高精度加法
    $res = [];
    foreach ($weightMap as $key => $weight) {
        $res[$key] = bcdiv(bcmul($money, $weight, 2), $totalWeight, 2);
        $money = bcsub($money, $res[$key], 2);
        $totalWeight = bcsub($totalWeight, $weight, 4);
    }
    return $res;
}
运行结果
echo json_encode(equallyMoney(20, ['张三' => 3, '李四' => 3, '王五' => 3, '赵六' => 3, '孙七' => 3, '周八' => 3]), JSON_UNESCAPED_UNICODE);

{"张三":"3.33","李四":"3.33","王五":"3.33","赵六":"3.33","孙七":"3.34","周八":"3.34"}  // 共20

最后大家拿到钱,看看人别,感觉不是大亏。于是就散了。

王老师终于能睡个好觉了,他发誓,再也不帮学校分钱了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值