Josephus算法部分成功

时间:2018-07-23 14:19:20

标签: python algorithm josephus

我的朋友告诉了我Josephus problem的情况,您有41个人坐在圈子中。人号1拥有一把剑,杀死右边的人并将剑传递给下一个人。这一直持续到只有一个人活着。我在python中想出了这个解决方案:

print('''There are n people in the circle. You give the knife to one of 
       them, he stabs person on the right and
       gives the knife to the next person. What will be the number of whoever
       will be left alive?''')

pplList = []
numOfPeople = int(input('How many people are there in the circle?'))


for i in range(1, (numOfPeople + 1)):
    pplList.append(i)
print(pplList)

while len(pplList) > 1:
    for i in pplList:
        if i % 2 == 0:
            del pplList[::i]
    print(f'The number of person which survived is {pplList[0]+1}')
    break

但是最多只能使用42个人。我应该怎么做,或者我应该如何更改代码,以使其适用于100, 1000等圈子中的更多人?

我查看了约瑟夫斯问题,并看到了不同的解决方案,但是我很好奇我的答案经过一些细微调整后是否正确,还是应该从头开始。

2 个答案:

答案 0 :(得分:1)

我看到了两个严重的错误。

  1. 我保证del ppList[::i]不会做任何您希望做的事情。
  2. 绕圈时,重要的是要知道是杀死列表中的最后一个人(列表中的第一人再次杀死)还是没有杀死(列表中的第一人死亡)。

与您断言它可以达到42的说法相反,它不适用于许多较小的数字。第一个不起作用的是2。(给出的答案是3而不是1。)

答案 1 :(得分:0)

问题是,如果他没有被杀死,那么最终您不会考虑他。例如,如果有9个人,则在杀死8个人之后,会有9个人拥有剑,但是您只是从1开始,而不是在下一个循环中有9个人。正如有人已经提到的,它也不适用于较小的数字。实际上,如果您看上去很近,那么您将在第一个循环中杀死奇数,而不是偶数。这是非常错误的。

您可以按照以下步骤更正代码

while len(pplList )>1:
    if len(pplList )%2 == 0:
        pplList  = pplList [::2] #omitting every second number
    elif len(pplList )%2 ==1:
        last = pplList [-1] #last one won't be killed
        pplList  = pplList [:-2:2]
        pplList .insert(0,last) # adding the last to the start

除此方法外,还有许多非常有效的方法可以解决问题。检查this link以了解更多信息