將10000塊錢分成5份,且每一份之間的相差的值$d不一樣,并且相差$d得大于100。
用php解決一個小算法,求思路。
喵喵時光機
2019-05-21 17:26:49
TA貢獻1777條經(jīng)驗 獲得超3個贊
謝邀!對隨機的五位數(shù)排序,最小在前最大在后的依次增大前4次是隨機值第5次是總數(shù)減去前四次隨機值重要的就是前四次隨機值的范圍,就是其中的最小值和最大值。這時候如果最小值和最大值限制越多到后面越容易產(chǎn)生隨機值,并且要保證最小值要大于前一個隨機值的100以上。而關(guān)于最大值就簡單多了,盡可能小,但是不會比最小值小。并且不會比我下面例子中使用的最大值($rand_max)大。(至于為什么你可以思考下)如果產(chǎn)生的隨機值中差值產(chǎn)生重復(fù),那么就重新產(chǎn)生隨機值$sum=10000;$diff=100;$count=5;$return=array();$min=0;$i=1;while($i<$count){//隨機數(shù)不符合要求時的結(jié)果初始化if(isset($return[$i])||isset($return[$i+1])){unset($return[$i]);unset($return[$i+1]);}//剩余數(shù)$remain_sum=$sum-array_sum($return);//剩余需要隨機的個數(shù)$remain_count=intval($count-count($return));//高斯求最小差值和,分兩部分:S=n(n+1)(2n+4)/12+$diff*((n-1)(n-2)/2)$min_diff=$remain_count*($remain_count-1)*(2*($remain_count-1)+4)/12+($remain_count*($remain_count-1)/2)*$diff;//隨機范圍的最小值$min=$i==1?1:$return[$i-1]+$diff+1;//在范圍內(nèi)獲取隨機數(shù)mt_srand((double)microtime()*1000000);//隨機范圍的最大值$rand_max=intval(($remain_sum-$min_diff)/$remain_count);//產(chǎn)生隨機數(shù)$min=mt_rand($min,$rand_max);//放入返回的數(shù)組$return[$i]=$min;if($i==$count-1){//最后一個隨機數(shù)直接取總數(shù)減去前面的隨機數(shù)$return[$i+1]=$remain_sum-$min;}if(check_diff($return)===false){$i--;continue;}$i++;}var_dump($return);die;//判斷數(shù)組內(nèi)是否有差值相等functioncheck_diff($arr){if(empty($arr)){returnfalse;}$arr=array_map('intval',$arr);sort($arr);$count=count($arr);$diff_arr=array();for($i=$count-1;$i>=0;$i--){for($j=0;$j<$count;$j++){if($arr[$i]<=$arr[$j]){continue2;}$diff_arr[]=$arr[$i]-$arr[$j];}}if(count($diff_arr)===count(array_unique($diff_arr))){returntrue;}returnfalse;}
TA貢獻1812條經(jīng)驗 獲得超5個贊
functionsplitMoney($money,$num,$difference){$arr=array();$v=$money/$num;for($i=0;$i<$num-1;$i++){$cur=mt_rand($difference,$difference+($difference/2));if($arr[$i]==0){$arr[$i]=$v-($cur/2);$arr[$i+1]=$v+($cur/2);}else{$arr[$i+1]=$v+$cur;}}return$arr;}偽代碼如上,另外你需要處理總和不等于實際金額的問題。
舉報