上週面試一家公司,被總監問到發紅包的這個問題。當時處於緊張腦子裏一篇空白。所以沒有答出來如何正態分佈這些紅包,每個人都有錢拿,而且隨機。今天想了下才想出答案。
假設有有10元錢 ,發給10個人。保證每個人都有錢拿,最少分得0.01。我們最先想到的肯定就是隨機。0.01-10隨機。但是會出現第一個人就分得9.99的情況。下面就沒人可分了。然後就是我的錯誤思路 ,先保證每個人至少分到0.01,然後每次隨機。減去發出的金額。但是這個前面的人隨機的跨度大,所以越到後面金額越小。這也是不允許的。那麼我們設置一個安全的金額區,從0.01到這個安全的金額區來隨機。那麼這個安全的金額區怎麼設定。那也很簡單,當有幾個人 把剩餘的錢相除得出平均數,是不是可以讓每個人都得到錢了。
例如(金額按照分來算):
$total = 1000;
$min = 1;最小金額
$num = 10;
$i;// (第幾個紅包)
$safe_money;// 安全金額
$i=1; $safe_total=($total-($num-$i)*$min)/($num-$i);
$safe_money = (1000-(10-1)*1)/9;
$safe_money = 110.11;
那麼第一個人的紅包金額就是mt_rand($min,$safe_money)
剩餘錢數爲$total = $total-mt_rand($min,$safe_money);依次類推
代碼如下
$total=10;//紅包總金額
$num=10;// 分成10個紅包,支持10人隨機領取
$min=0.01;//每個人最少能收到0.01元
for ($i=1;$i<$num;$i++)
{
$safe_total=($total-($num-$i)*$min)/($num-$i);//隨機安全上限
echo "安全金額".$safe_total."<br>";
$money=mt_rand($min*100,$safe_total*100)/100;
$total=$total-$money;
echo '第'.$i.'個紅包:'.$money.' 分,餘額:'.$total.' 分 ';
echo "<br>";
}
echo '第'.$num.'個紅包:'.$total.' 分,餘額:0 分';
====================================================================
第一次輸出輸出爲:
110.11111111111
第1個紅包:47 分,餘額:953 分
118.125
第2個紅包:6 分,餘額:947 分
134.28571428571
第3個紅包:79 分,餘額:868 分
143.66666666667
第4個紅包:138 分,餘額:730 分
145
第5個紅包:57 分,餘額:673 分
167.25
第6個紅包:100 分,餘額:573 分
190
第7個紅包:153 分,餘額:420 分
209
第8個紅包:30 分,餘額:390 分
389
第9個紅包:73 分,餘額:317 分
第10個紅包:317 分,餘額:0 分
======================================================================
第二次輸出:
110.11111111111
第1個紅包:96 分,餘額:904 分
112
第2個紅包:93 分,餘額:811 分
114.85714285714
第3個紅包:61 分,餘額:750 分
124
第4個紅包:109 分,餘額:641 分
127.2
第5個紅包:83 分,餘額:558 分
138.5
第6個紅包:129 分,餘額:429 分
142
第7個紅包:87 分,餘額:342 分
170
第8個紅包:166 分,餘額:176 分
175
第9個紅包:147 分,餘額:29 分
第10個紅包:29 分,餘額:0 分