算法:生日吹蠟燭

題目:一個人從某歲生日開始,每年都會吹蠟燭,給定他吹的蠟燭總數,求出他所有連續吹蠟燭的年齡組合。

思路:轉換成給定一個數,求出連續整數相加之和等於目標數的所有組合

  1. 當前連續年齡個數 + 1,再除以2,然後乘以當前年齡個數,如果大於蠟燭數,直接break,其實就是我們小學學的,求1-100的和是多少,(1+100) * 100 / 2,(舉個栗子:比如當前蠟燭數是6,最多隻能分成連續3年吹,假如連續4年吹,就算一生下來一歲就開始吹,連着吹4年,1,2,3,4加起來也大於6)
  2. 一個數a是奇數, 另一個數b除以a能整除,那麼一定存在a個連續的整數相加等於b,並且商就是這a個數的中位數
  3. 一個數a是偶數, 另一個數b除以a,結果爲c,假如c的小數部分爲5,那麼一定存在a個連續的整數相加等於b,同時c向下取整和向上取整,就是這a個數的中間兩個數)

代碼:

<?php

//給定一個數,判斷能由哪些連續的數相加組成

$target = 3;
$res = [];
for ($n = 2; $n <= $target; $n++) {
    if ( ((1 + $n) * $n / 2.0) > $target){
        break;
    }

    $tmp = $target / floatval($n);
    if ($n % 2 == 1){
        //積數個
        $tmp_res = $target / floatval($n);
        if ( intval($tmp_res) == $tmp_res ){
            $tmp_num = ($n - 1) / 2;

            $item = [
                $tmp_res,
            ];
            $count = 1;
            while ($tmp_num >= $count){
                $item[] = $tmp_res - $count;
                $item[] = $tmp_res + $count;
                $count++;
            }
            sort($item);
            $res[] = $item;
        }
    }else{
        //偶數個
        $tmp_res = $target / floatval($n);
        if ( $tmp_res == intval($tmp_res)){
            continue;
        }
        $tmp_arr = explode('.', $tmp_res);
        if ( $tmp_arr[1] * 2 == 10){
            $tmp_res = floor($tmp_res) - ($n / 2 - 1);

            $item = [
                $tmp_res,
            ];
            $count = $n - 1;
            while ($count){
                $item[] = $tmp_res + $count;
                $count--;
            }
            sort($item);
            $res[] = $item;
        }
    }
}

print_r($res);

結果:

[why@localhost] ~/Desktop/php$php birthday_candle.php 
Array
(
    [0] => Array
        (
            [0] => 5
            [1] => 6
            [2] => 7
        )

    [1] => Array
        (
            [0] => 3
            [1] => 4
            [2] => 5
            [3] => 6
        )

)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章