1. 程式人生 > 實用技巧 >js解決約瑟夫問題

js解決約瑟夫問題


// 用陣列的方式解決
function getLastNum(n,m) { if(n <= 1 || m < 1) return; let arr = new Array(n).fill(1); let count = 0 ; // 記錄出圈人數 let num = 0; // 報時器 while(count < n -1) { for(let i = 0; i < arr.length; i++) { if(arr[i] === 1) { num++;   if(num === m) {// 當遇到相同的那個時出局, // 並將該值標記為0 表示已出局,同時出局人數加1 報數重新初始化 arr[i] = 0; count++; num = 0; } } } if(count === n -1) { break; } } let lastNum for(let i = 0; i < arr.length;i++) { if(arr[i] === 1) { lastNum = i + 1; break } } return lastNum; }

 注: 傳說羅馬人佔領了喬塔帕特,41 個猶太人被圍堵在一個山洞裡。他們拒絕被俘虜,而決定集體自殺,大家決定了一個自殺方案,41 個人圍成一個圈,由第 1 個人開始順時針報數,每報數為 3 的人立刻自殺,然後再由下一個人重新從 1 開始報數,依舊是每報數為 3 的人立刻自殺,依次迴圈下去。其中兩位猶太人並不想自殺,是數學家約瑟夫和他的朋友,他們發現了自殺方案的規律,選了兩個特定的位置,最後只剩下他們兩人,而活了下來。那麼這兩個位置分別是什麼?

// 使用遞迴方式實現
/*
n 個人,只要有一個人出局,就變成了n-1個人,此時要處理的問題就是n-1個
依次類推,要處理的就是n=2 的問題,當n= 1 時,遊戲結束
用一個方法來表示就是f(2,m)
然後要找f(3,m)和f(2,m)的對應關係,準確的說是f(n,m)和f(n-1,m)的關係

*/

/*當n = 5,m = 2;
0 1 2 3 4 從0開始 1是第一個出局的
0 2 3 4 出局的第一個數

2 3 4 0 (*)上面可以寫成這樣,因為是從2開始的
0 1 2 3 (**)n= 4 ,m= 2,是接下來要處理的事
0 2 3 出局的第二個數
比較(*)和(**)的規律 ((**)+ 2)% 5 這可轉化為(*)注: * 代表出局的數

上面的可以寫成下面這樣 ,因為是從2開始的
2 3 0 (*)
0 1 2 (**)
((**)+ 2)% 4 
*/


function getLastPerson(n,m) {
  let r = 0;
  for(let i = 2; i <= n; i++) {
    r = (r + m )% i;
   }

  return r + 1;
}