1 约瑟夫问题描述
在古罗马人占领乔塔帕特后,39个犹太人与约瑟夫和他的朋友躲到一个洞中。39个犹太人决定宁死也不被敌人抓到,于是商定以一种特殊的方式自杀: 41个人排成一个圆图,由第一个人开始报数,每报数到3的人就必须自杀,直到所有人都自杀身亡为止。但是约瑟夫及其朋友并不想死,那么请问约瑟夫及其朋友应该怎样安排自己的位置才能逃过一劫?
2 问题分析
如果约瑟夫及其朋友不想死,那么他们将是最后剩下的两个人,因此,问题的关键在于如何安排他们的位置才能将他们留到最后。
3 Python程序模拟
下面我们用程序模拟这个自杀过程,找出最后两个人的位置,这两个位置就是约瑟夫及其朋友的位置。
def move(man,sep):"""将man列表向左移动sep单位,最左边的元素向列表后面添加,相当于队列顺时针移动"""for i in range(sep):item = man.pop(0)man.append(item)def play(man=41,sep=3,rest=2):"""man:玩家个数sep:杀死数到的第几个人rest:幸存者数量"""print('总共%d个人,每报数到第%d的人自杀,最后剩余%d个人'%(man,sep,rest))man=[i for i in range(1,man+1)] #初始化玩家队列print("玩家队列:",man)sep-=1 #数两个数,到第3个人时就自杀while len(man)>rest:move(man,sep)print('kill',man.pop(0))return manservive=play()print("最后逃生的人编号是:",servive)
测试及运行结果如下:
总共41个人,每报数到第3的人自杀,最后剩余2个人玩家队列: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41]kill 3kill 6kill 9kill 12kill 15kill 18kill 21kill 24kill 27kill 30kill 33kill 36kill 39kill 1kill 5kill 10kill 14kill 19kill 23kill 28kill 32kill 37kill 41kill 7kill 13kill 20kill 26kill 34kill 40kill 8kill 17kill 29kill 38kill 11kill 25kill 2kill 22kill 4kill 35最后逃生的人编号是: [16, 31]Process finished with exit code 0
因此,约瑟夫和他朋友如果想要逃生的话,就得把他自己和朋友放到第16和31个位置上,以保证他们是最后的两个玩家。
