用隊列解決Josephus(約瑟夫)問題
什麼是約瑟夫問題:(來源:百度百科)
據說著名猶太歷史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺身亡爲止。然而Josephus 和他的朋友並不想遵從。首先從一個人開始,越過k-2個人(因爲第一個人已經被越過),並殺掉第k個人。接着,再越過k-1個人,並殺掉第k個人。這個過程沿着圓圈一直進行,直到最終只剩下一個人留下,這個人就可以繼續活着。問題是,給定了和,一開始要站在什麼地方纔能避免被處決?Josephus要他的朋友先假裝遵從,他將朋友與自己安排在第16個與第31個位置,於是逃過了這場死亡遊戲。
隊列定義:
class Queue(object):
# 我們把list的尾當作queue的頭,list的頭當作queue的尾,這樣方便我們
# 利用list的現有函數進行操作
def __init__(self):
self.items = []
def size(self):
return len(self.items)
def enque(self, x):
self.items.insert(0, x)
def deque(self):
return self.items.pop()
def isEmpty(self):
return len(self.items) == 0
解決算法
def Solution(people, num):
"""
input:opeple -> 參與的人的list
num -> 報到幾被選中
"""
# 定義隊列
queue = Queue()
# 將人加入到隊列
for i in people:
queue.enque(i)
# 遊戲開始
while(queue.size() > 1): # 當隊列裏不止一個人時
for i in range(num):
queue.enque(queue.deque()) # 把隊首元素移到隊尾,相當於傳遞一次
queue.deque() # 一次結束後,刪除隊首
return queue.deque()
測試:
print(Solution(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'], 7))
結果: