【循环链表】约瑟夫环问题——Python

背景:故事源自著名犹太历史学家Josephus,在罗马人占领乔塔帕特后,39个犹太人与Josephus以及他的朋友躲进了一个山洞中,39个犹太人决定宁死不屈,于是决定了一个自杀方式,41个人排成一个圈,由第一个人开始报数,每数到3此人就自杀,然后由下一个重新报数,直到所有人都自杀为止。然而Josephus和他的朋友并不想这就死去,于是Josephus让他的朋友和他佯装遵从,他偷偷将朋友和自己安排在第16个和31个位置,最终逃过了这场死亡游戏。
 

以上就是经典的约瑟夫环问题,简单转换:

有n个人围成一圈(1~n),从第1号开始进行1、2、3报数,凡报3者就退出,下一个人又从1开始报数......直到所有人退出圈子为止。输入整数n,请按顺序输出退圈顺序

解题思路:可参考b站:约瑟夫问题,讲成这样,应该80老大爷都能听懂了_哔哩哔哩_bilibili

该up讲的非常清楚,但是源代码是C++,自己转换了一下为Python,其中遇到bug一直陷在了死循环,最后发现是while循环条件出错,基本代码和up的差不多,只是改动了一个条件

 (定义如果圈里有人的位置即为1,无人的位置即0;引入一个模拟裁判,设定mouth为数数,手指finger作为指针同时进行数数,当mouth数到3,指针停止,指针finger指到的位置赋值0)

#定义如果圈里有人的位置即为1,无人的位置即0;引入一个模拟裁判,设定mouth为数数,手指finger作为指针同时进行数数,当mouth数到3,指针停止,指针finger指到的位置赋值0

import numpy as np

game = np.zeros((20,), dtype=int) #创建一个长度为20的全零数组

res = [] #存储输出顺序的数字

n = 10 #圈里共有10个人
m = 3 #依据题目数到3退圈

for i in range(n): #为全零数组的前十个位置赋值为1(0~9)
    game[i] = 1

finger = 0
mouth = 0 

#游戏开始到结束
count = n
while count !=1: #小心这里应该为1,若为0会死循环在第一个while跳不出来,当输出最后一个人退圈时,count只到1
    finger += 1
    mouth += 1

    #当循环完第一圈时会有位置赋0,所以当指针finger指到为0的位置需要再跳一个即+1往下
    while game[finger] == 0:
        finger += 1
        if finger > n: finger = 1 #这里当循环到finger大于n时应该指回原来圈圈的第一位其下标在数组为0,但是当我们进入循环时finger已经先+1,所以finger=1时指向了1号,所以这时返回finger=1才是等于原来的1号

    if mouth == m:
        res.append(finger)
        count -= 1
        game[finger] = 0
        mouth = 0 #这里为0是因为在返回循环时mouth先+1,为了符合数数从1开始,这里应该为0
   
print(res)

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值