學習筆記 Josephus問題

2021-08-19 02:48:29 字數 3124 閱讀 9014

一、第一種方式,將表list看為元素固定的物件,即只修改元素的值而不改變表的結構——不加入或刪除表元素。

相當於擺了一圈n把椅子,人可以走但椅子在那裡且位置不變。沒有人時用0來

初始處理過程中採用把相應的表元素修改為0的方式來表示出列,反覆做

n個人出列即結束

def josephus(n, k, m):

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

i =k -1

for num in range(n): #每迴圈一次,乙個人出列(設為0)

count = 0

while count < m:

if people[i] > 0: #第i人未出列時,報「1」,計數器加一

count += 1

if count == m: #計數器加到m(數到第m個人時)

print(people[i], end="")

people[i] = 0

i = (i+1) % n #i自加一,直到超過人數n時,重置

if num < n-1:

print(", ",end="")

else:

print("")

return

二、採用出列的方式排,每齣列一次,表長度減1

def josephus_a(n, k, m):

l = [i for i in range(1,n+1)]

flag = #記錄出列人序號

count = 0

while len(l) is not 1:

l1 = l[k:] #以第k個人為起始點,對人數list進行重排

l2 = l[:k]

l = l1+l2

if count == 0:

k = m - 2 #對起始點人單獨處理(下標從0開始)

count = 1

else:

k = m - 1

if len(l) < m: #當人數列表list中人數小於報數間隔時,取餘再進行

else:

return flag

三、對於二的改進型做法

def josephus_b(n, k, m):

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

num, i = n, k-1

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

i = (i + m-1) % num

print(people.pop(i),end=(", " if num > 1 else "\n"))

return

四、採用迴圈單鏈表方式

實現的方式類似於二,只是二中需要手動對表單進行合併生成新錶,迴圈鍊錶也是將此過程看作是結點的轉動過程。只需要對鍊錶的next域進行設定即可。

class linkedlistunderflow(valueerror):

pass

class lnode:

def __init__(self, elem, next_=none):

self.elem = elem

self.next = next_

#迴圈單鏈表

class lclist:

def __init__(self):

self._rear = none

def is_empty(self):

return self._rear is none

def prepend(self, elem):

p = lnode(elem) #要進行插入的前端結點

if self._rear is none: #由於是迴圈鍊錶,如果尾結點為空,表明這個表是空表

p.next = p

self._rear = p

else:

p.next = self._rear.next

self._rear.next = p

self.prepend(elem)

self._rear = self._rear.next

def pop(self):

if self._rear is none:

raise linkedlistunderflow("in pop of cllist")

elif self._rear.next is self._rear:

p = self._rear.next.elem

self._rear = none

return p

else:

p = self._rear.next.elem

self._rear.next = self._rear.next.next

return p

def printall(self):

if self.is_empty():

return

p = self._rear.next

while true:

yield p.elem

if p is self._rear:

break

p = p.next

class josephus(lclist):

def turn(self, m):

for i in range(m):

self._rear = self._rear.next

def __init__(self, n, k, m):

super().__init__()

for i in range(n):

self.turn(k-1)

while not self.is_empty(): #若當前的鍊錶非空,則進行結點的刪除

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...

Josephus問題總結

josephus問題 n個人排成乙個圈,從其中個人從1開始報數,數到m的人自動出列,接著下乙個人又從1開始報數。如此迴圈往復,直到只剩下乙個人,則此人獲勝。假設出列的人是被斃了,這時你有兩個方式 1 標記法 記錄完所有loser,最後判斷出winner時,再把loser一起斃掉 2 直接刪除法 數到...