• 抢红包算法——线段分割法


    抢红包算法经常在面试的时候被问到,那么今天我就给大家分享一个比较常用容易理解的算法,线段分割法的实现。

    算法思路:

    线段分割法就是把红包总金额想象成一条线段,而每个人抢到的金额,则是这条主线段所拆分出的子线段。

    当N个人一起抢红包的时候,就需要确定N-1个切割点。

    因此,当N个人一起抢总金额为M的红包时,我们需要做N-1次随机运算,以此确定N-1个切割点。

    随机的范围区间是(1, M)。当所有切割点确定以后,子线段的长度也随之确定。这样每个人来抢红包的时候,只需要顺次领取与子线段长度等价的红包金额即可。

    需要注意:

    1、每个人最低也要抢到1分钱,要保证不能抢到0元的情况;

    php代码实现:

    <?php

    $num = 4; //红包个数

    $money = 100; //红包钱数100元

    $money_fen = $money * 100; //元转换成分

    //从1至总金额*100中,随机取4-1个随机数

    $i = 1;

    $rand = [];

    while ($i < $num)

    {

    //$money_fen需要减1 不然最后一个人可能抢到0元

    $rand_num = mt_rand(1,$money_fen-1);

    //如果已经存在该随机数不保存,主要解决抢到0元的情况

    if(!in_array($rand_num,$rand,true))

    {

    $rand[] = $rand_num;

    $i+=1;

    }

    }

    //从小到大排序

    sort($rand);

    //中奖结果

    $result = [];

    foreach ($rand as $key =>$value)

    {

    if($key == 0)

    {

    $result[] = $value;

    }

    else

    {

    $result[] = $value - $rand[$key - 1];

    }

    }

    //最后一个人的中奖结果

    $result[] = $money_fen - $rand[count($rand) - 1];

    //转化成元

    foreach ($result as $key=>$value)

    {

    $result[$key] = $value / 100;

    }

    print_r($result);

  • 相关阅读:
    eval()函数的使用
    Ajax的GET,POST方法传输数据和接收返回数据
    使用目录
    安装目录
    c 文件输入和输出
    【C++王桂林】
    【C++】虚函数表vtable理解
    【C++】内存管理内幕阅读笔记
    git提交中的索引错误问题
    pydicom编辑、删除DICOM文件中病人相关信息
  • 原文地址:https://www.cnblogs.com/wish123/p/12974581.html
Copyright © 2020-2023  润新知