鍍金池/ 問答/PHP  HTML/ 用php解決一個小算法,求思路。

用php解決一個小算法,求思路。

將10000塊錢分成5份,且每一份之間的相差的值$d不一樣,并且相差$d得大于100。

回答
編輯回答
小眼睛

謝邀!

  1. 對隨機的五位數(shù)排序,最小在前最大在后的依次增大
  2. 前4次是隨機值
  3. 第5次是總數(shù)減去前四次隨機值
  4. 重要的就是前四次隨機值的范圍,就是其中的最小值和最大值。這時候如果最小值和最大值限制越多到后面越容易產(chǎn)生隨機值,并且要保證最小值要大于前一個隨機值的100以上。而關(guān)于最大值就簡單多了,盡可能小,但是不會比最小值小。并且不會比我下面例子中使用的最大值( $rand_max )大。(至于為什么你可以思考下)
  5. 如果產(chǎn)生的隨機值中差值產(chǎn)生重復(fù),那么就重新產(chǎn)生隨機值
    <?php
    
    $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)是否有差值相等
    function check_diff($arr) {
        if(empty($arr)) {
            return false;
        }
        
        $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]) {
                    continue 2;
                }
                $diff_arr[] = $arr[$i] - $arr[$j];
            }    
        }
        
        if(count($diff_arr) === count(array_unique($diff_arr))) {
            return true;
        }
        
        return false;
    }
2018年8月15日 04:10
編輯回答
脾氣硬
function splitMoney($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;
}

偽代碼如上,另外你需要處理總和不等于實際金額的問題。

2018年4月22日 13:22