演算法 Josephus問題 報數遊戲

2021-08-31 23:25:59 字數 1723 閱讀 9861

問題描述:有n

個人圍成一圈,按順序排號。從第乙個人開始報數(從

1開始),凡報到

5的人退出圈子,問最後留下的是原來第幾號的那位。

例如:9個人圍成一圈,

1號從第

1開始報數,

5號首先退出圈子。接著6號從

1開始重新報數,

1號退出圈子。接著2號從

1開始重新報數,

7號退出圈子。然後從

8號開始重新報數,

4號退出圈子。

6號重新報數,

3號退出圈子。依次類推,最後剩下原來的

8號留下

已有檔案

in.txt。輸入檔案格式如下:

656 786

5479 3423

檔案裡每一行為乙個整數

n,表示每一輪遊戲有

n個人參與報數。以回車換行。

輸出最後留下的人員編號

解題:理解題目後發現,這是乙個josephus問題,總共包含n個人,從第k(k=1)個人開始數數,數m個之後退出,依次迴圈

首先需要將n個人對映到乙個長度為n的陣列中people[0]...people[n-1]對應[1,n],注意下標和編號的對應(編號1的下標為0),針對約瑟夫問題,兩種方法:

需要注意:經過幾輪的訪問之後,陣列的下標可能已經超過了陣列長度,需要將陣列下標取模對映到原陣列中

2.列表方式:掃瞄陣列,如果數到m時,則將對應的數從列表中出列,直到陣列長度變為1

#陣列方式,n:陣列長度,k:開始編號,m:數的個數;

def josephus_a(n,k,m):

people = list(range(1,n+1))

i = k - 1

for num in range(n):

count = 0 #count:計數器

while count < m:

if people[i] > 0:

count += 1

if count == m:

print(people[i],end=' ') #退出的人

people[i] = 0 #編號設為0

i = (i+1)%n

if num < n - 1:

print(", ",end="")

elif num == n - 1:

print("最後留下:",people[i])

else:

print(" ")

return

def josephus_l(n,k,m):

people = list(range(1,n+1))

num, i = n, k-1

for num in range(n-1,0,-1):

i = (i+m-1)%num

print(people.pop(i),

end=(", " if num > 1 else "\n"))

print("最後留下:",people[0])

return

#測試with open(filename,'r',encoding='utf-8') as fp:

lines = fp.readlines()

for line in lines:

line = line.rstrip('\n')

n = int(line)

k = 1

m = 5

josephus_a(n,k,m)

趣味演算法(一)Josephus問題

josephus問題求解 設有n個人圍坐乙個圓桌周圍,現從第s人開始報數,數到第m的人出列,然後從出列的下乙個重新開始報數,數列的第m個人又出列 如此重複,直 到所有的人全部出列為止。對任意給定的n s m,求按出列次序得到的n個 人員的順序表。分析 對於n個人,每一次出列乙個人,餘下的n 1個人仍...

Josephus 約瑟夫 問題

問題描述 已知n個人 以編號1,2,3.n分別表示 圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到剩下最後乙個人。程式的意圖是求出最後留下的人的編號。c 實現 include include include u...

約瑟夫(Josephus)問題

一群小孩圍成一圈,任意假定乙個數n,從第乙個小孩起,順時針方向數,每數到第m個小孩時,該小孩便離開。小孩不斷離開,圈子不斷縮小。最後剩下的乙個小孩便是勝者。求勝者的編號?函式名稱 josephus 作 成 者 erick.wang 作成日期 2016 07 19 返 回 值 void 參 數 m,n...