zoukankan      html  css  js  c++  java
  • 抢红包算法——线段分割法

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

    算法思路:

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

    当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);

  • 相关阅读:
    evernote100个做笔记的好方法
    平衡二叉树的调整模版
    晨间日记的奇迹
    hdu 2952 Counting Sheep
    hdu 1535 Invitation Cards
    poj 3259 Wormholes(spfa)
    poj 2263 Heavy Cargo(floyd)
    poj 3268 Silver Cow Party(SPFA)
    hdu 1690 Bus System
    hdu 3631 Shortest Path(Floyd)
  • 原文地址:https://www.cnblogs.com/wish123/p/12974581.html
Copyright © 2011-2022 走看看