以前想过一个类似问题,就是没有每个人最大、最小的得钱数的限制,以前的问题可以很好用随机数解决。
于是这个问题也被以前的思想带坑里了,把突破口完全放在了如何处理每个人的随机数上。
于是在面试时间就没有解决这个问题,直到面试结束自己安静下来,仔细想想,发现思路错了。
我认为正确的思路是:每个人先得6块钱,这样剩下40块钱,之后每次拿出一块钱,随机分配给一个人,如果某个人的钱数达到了上限,那么这个人下次就没有了再得到钱的资格了。这样直到剩下钱都分配完。
当然在接口的实际处理上可以做些优化,例如剩下的钱每次随机分配的钱可以是随机的(当然这个随机要做一些限制,以免一下就分配超额了),然后如果某个人钱+这次随机分配的钱>每个人的上限,那么他就没有资格得到这个钱了。
随机分配也好实现,先算有几个人有资格得到这笔钱,随即一个数,决定给第几个符合资格
的人。
我的思路就是这样,大家如果有更好的思路,请告知。谢谢。
如题,首先要获取大于6小于12的随机数,那么只要我们随机出0-6的随机数,并且加上6,就是符合要求的。
然后这个是红包,按照微信红包的需求来设计,那么随机数是有两位有效小数的。那么我们需要随机出0-600的随机数,然后除以100。
因为这种设计,所以随机出来的数值一定大于6,所以6这边边际问题,就解决了,只需要考虑12的情况。
随机出来一个数字,只要确保后面的n位数字的平均值不大于600就可以。
算法就是这样,结果一定是正确的。
算法中添加的$factor_start和$factor_end变量,就是为了提高算法效率。
假设前面的随机数都很小,那么后面的随机数就要大起来。这个时候就需要增大$factor_start,减少后面while循环次数,提高算法效率。
假设前面的随机数特别大,让后面的数,无法满足0,到600的随机,那么就通过$factor_end来控制。
答案真多,也没仔细看, 不知道有没有和我一样想法的。
我的总体思路是这样的:先均分6块;再分析每个人得钱的随机范围;每个人依次得钱直至分完,一次就分完了。
1、每人至少6块,所以先分出60,剩下40。那剩下人的每个人能得到的初看是[0~6];
2、反推。从最后一个人(第10个人)推起,到他时,剩下的钱必定是<=6,继续往前推一个,到他时,剩下的钱必定是<=12,然后依次类推(最好在纸上写一下)。这么推我们可以得出到第5个人得钱时,剩下的钱必定是<=36, 那么前4个人必须要分掉至少4块钱,以此再推,前5个人必定要分掉至少10块钱,至最后一个至少得分掉34块钱。这样通过找规律我们得出了每个人得钱的随机范围的第一个值。
3、虽然我们得出了每个人随机范围的第一个值,但并不是每一个人的随机范围的第二个值都是 6,因为当前面的几个人已经把大部分钱都分了的时候,后面的人就没得分了。这次,我们从第一个人开始往后推,当到第N个人时剩下的钱$R<6时,这个人所能分得的钱的随机范围第二个值就是剩下的钱$R,然后他后面的人所能分得的钱的随机范围的第二个值还是$R;
说明完毕,也不知道有没有说明白,还是直接上代码吧:
这里得出的都是整型的,如果要得到浮点数,把rand函数替换成获得浮点数的随机函数就行。这是稍微精简后的,通俗过程:
困死了,不写了
作为热门问题 前端人员表示想过来贴个 JavaScript版
楼主的方法只能处理整数问题吧,题目中并没有交代一定是整数。
每次取随机的范围都是变化的
下限从6和(剩余钱数-12*(剩余人数-1))中取大的
上限从12和(剩余钱数-6*(剩余人数-1))中取小的
贴Java代码
某次运行截图
这么多人会,就我不会