PHP丟手帕問題執行個體詳解

來源:互聯網
上載者:User
問題描述:有n個人圍成一圈,然後從任意指定的一個 人那裡為起點,以m個人為單位,每轉m個人第m個人被殺死。求最後不會被殺死的人。

遺留問題:

在此用php做簡單的實現,php中對遞迴有100次的深度限制,所以在此不用遞迴,用迴圈;php中處理數組的函數比較多,所以採用順序表(數組),順序表刪除元素比較複雜,所以效率比較低,只能處理10000一下的資料。鏈表中的遍曆比較複雜,同樣會導致效率低下,以後再做順序表與鏈表的結合。

類比實現:

  1. class Dhc  {      private function dropHandkerchief($start=0,$distance,$menArray)      {          $count = count($menArray);            $pos = $distance - 1;            $start = $start > ($count-1) ? 0 : $start;//開始位置大於總人數則預設從第一個開始            $pos = $start + $pos;//第一個要被出列的人的位置,pos為下標,所以要 -1;            while($count > 1)            {                if($pos < $count)//判斷要出列的人的位置是否超出數組大小,超出則減去(或模數)數組大小,從頭開始                {                    echo "第". $menArray[$pos] ."人出列<br />";                    array_splice($menArray,$pos,1);//刪除要出列的人                    $count  = count($menArray);//重新計算大小                    $pos += $distance - 1;//下一個要出列的人的位置,pos 為要數的第一個人,所以第 n 個人的下標為 pos + n -1                }else                {                    //$pos -= $count;                    $pos = $pos % $count;                }          }            echo '<br />';            echo "第" .$menArray[0]. "人被留下";        }          public function drop()      {          $menArray = array();//            $total = 100;//總人數            $distance = 50;//間隔人數            $start = 3;//從第幾個人開始            $i = 0;            while($i < $total)//初始化            {                $menArray[$i] = $i + 1;                $i++;            }            $this->dropHandkerchief($start, $distance, $menArray);        }  }

數學推導實現:(20170914)

簡單改變一下問題的描述:有 n 個人,編號是 0 - n-1,從 0 開始數,數到 m 則 m 死,下一個人繼續從 0 開始數,直到只剩最後一個人,求這個人最開始的編號。

每死一個人就重新開始,相當於減小了問題的規模,就是要解 n 個規模的解:n, n-1, n-2, n-3 …… 3, 2, 1。

假如在第二輪(n-1個人的規模)中死的那個人編號是 x(這個編號是第一個人死後,重新從 0 開始編排的),則可以推匯出這個人在第一輪(人數為 n 時)中的編號是:(x + m)%n。

(n-2)中死的人在(n-1)中的編號是:(x + m)%(n-1)

(n-3)中死的人在(n-1)中的編號是:(x + m)%(n-2)

( 1 )中死的人在( 2 )中的編號是:(x + m)%2, 此時 x = 0;

把上面的過程倒過來,已知規模為 1 時,x = 0;

求規模為 2 時,x2 的值:(x + m) % 2 = x2

求規模為 3 時,x3 的值:(x2 + m) % 3 = x3

求規模為 n 時 x 的值。

  1. $n = 100;  $m = 3;  $s = 0;    $x = 0;  for ($i=2; $i<=$n; $i++) {      $x = ($x + $m) % $i;  }  echo ($x + $s) % $n;  // $s=0,表示從第 0 個開始數,如果不是從 0 開始,則只需要向後推 $s 個即可

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.