pythonnnnnn脑筋急转弯-约瑟夫环求解

任务

编写一个使用列表求解约瑟夫环的问题

背景

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中。
39个犹太人决定宁愿死也不要被敌人抓。于是决定了自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀。然后下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
约瑟夫问题可以这样描述:n个人按1,2,3,… ,n编号,并顺序围坐一圈。开始按照1,2,3,… ,m 报数,凡报到 m 的出列。直到所有人出列为止。
在这里插入图片描述

求解

法一

从列表头开始遍历,设置一个计数器c,初始化设置为0,每次判断,都是判断计数器,若c==k(设置的序号)即表示当前数应当被剔除,剔除后计数器归0,遍历继续,但是c从头开始计数。具体思路如下图所示:

x=[]
n=eval(input("输入人数"))
k=eval(input("输入序号"))
x = [i for i in range(1,n+1)]
c = 0

# 当x不为空时进行循环
while x:
    temp = x[0]
    c = c + 1
    if c == k:
        print(temp)
        c = 0
        x.remove(temp)
    else:
        x.remove(temp)
        x.append(temp)

在这里插入图片描述
在这里插入图片描述

法二

法一是把它想成是一个直直的列表,遍历一直往后进行,法二是绕圈遍历,遍历到了末尾又从列表头开始。

循环下标index0开始,当列表只有最后一个元素时结束
第一个移除出列表的元素下标,len表示当前列表的长度:(0+(k-1))%len
第二个移除出列表的元素下标:(0+(k-1)+(k-1))%len
其实,也就是每次移除的元素,在数组中的位置index = (index + (k-1))%len

两个注意点
为什么要%len?因为是循环遍历,到了末尾需要从头继续,如1号,2号,3号三个人,依次报数,循环报数,取报数5的人,即2号。
为什么是index+(k-1)?虽然是往后数k个数,但是因为在前一阶段移除了1个符合要求的元素,所以在后一阶段符合要求的元素的下标其实只增长了k-1
在这里插入图片描述

x=[]
n=eval(input("输入人数"))
k=eval(input("输入序号"))
x = [i for i in range(1,n+1)]
index = 0
while True:
    if len(x) == 1:
        print(x[0])
        break
    index=(index+(k-1))%len(x)
    print(lb[x])
    del lb[x]

猜你喜欢

转载自blog.csdn.net/weixin_39333120/article/details/110421285
今日推荐