一个不简洁的约瑟夫环解法

约瑟夫环类似模型:已知有n个人,每次间隔k个人剔除一个,求最后一个剩余的。

此解法为变种,k最初为k-2,之后每次都加1。

例:n=5,k=3。从1开始,第一次间隔k-2=1,将3剔除,第二次间隔k-1=2,将1剔除。依此类推,直至剩余最后一个元素。

核心思路:将原列表复制多份横向展开,每次根据间隔获取被剔除的元素,同时将此元素存入一个剔除列表中。若被剔除元素不存在于剔除列表,则将其加入,若已存在,则顺势后移至从未加入剔除列表的元素,并将其加入。如此重复n-1次。面试遇到的题,当时只写了思路,没完成代码

#! /usr/bin/env python3
# coding = utf-8

def one_left(n, k):
    list0 = [i for i in range(1, n + 1)]  # 初始列表
    listx = []
    i = 0
    while i <= 2*n:
        i += 1
        listx += list0  # 根据循环次数得到扩大列表
    print("listx", listx)
    list1 = []  # 用于保存被筛掉的元素
    intervals = [l for l in range(k - 2, k - 2 + n - 1)]
    print(‘intervals‘, intervals)
    current_key = 0  # 当前下标
    for interval in intervals:  # 最外层循环,循环次数为n-1
        current_key += (interval + 1)  # 间隔数+1
        if listx[current_key] not in list1:  # 如果剔除元素不在list1中
            list1.append(listx[current_key])
        else:
            while True:
                if listx[current_key] in list1:
                    current_key += 1
                else:
                    break
            list1.append(listx[current_key])
    print(‘剔除列表为:‘,list1)
    print(‘剩余元素为:‘,set(list0)-set(list1))

def main():
    one_left(n=5, k=4)

if __name__ == ‘__main__‘:
    main()
时间: 2024-10-02 02:13:55

一个不简洁的约瑟夫环解法的相关文章

【好记性不如烂笔头】约瑟夫环问题之形象解法(其实就是实实在在的模拟一下游戏过程)

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace 约瑟夫环游戏 8 { 9 class Program 10 { 11 /* 12 * 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围. 13 * 从编号为k的

约瑟夫环的数学解法

CSDN链接 问题描述:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直到圆桌周围的人全部出列.求最后剩下的人的初始编号. 可以把问题转换成:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数.求胜利者的编号.则所得的解加1即为原问题的解: 一般我们采用一个循环队列来模拟约瑟夫环的求解过程,但是如果n比较大的时候,采用模拟的方

一个约瑟夫环问题

一个约瑟夫环问题 问题开始: 罗马人攻占了乔塔帕特,41个人藏在一个山洞躲过了这场浩劫.这41个人中,包括历史学家Josephus(约瑟夫)和特的一个朋友.剩余的39个人为了表示不向罗马人屈服,决定集体自杀.大家决定了一个自杀方案,所有这41个人围成一个圆圈,由第一个人开始顺时针报数,每报数为3的人就立刻自杀,然再由下一个重新开始报数,仍然是每报数为3的人立刻就自杀,....,直到所有的人都自杀身亡位置. 约瑟夫和他的朋友并不想自杀,于是约瑟夫想到一个计策,他们两个同样参与到自杀的方案中,但是最

小朋友学数据结构(1):约瑟夫环的链表解法、数组解法和数学公式解法

约瑟夫环的链表解法.数组解法和数学公式解法 约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,他参加并记录了公元66-70年犹太人反抗罗马的起义.约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷之后,他和40名死硬的将士在附近的一个洞穴中避难.在那里,这些叛乱者表决说"要投降毋宁死".于是,约瑟夫建议每个人轮流杀死他旁边的人,而这个顺序是由抽签决定的.约瑟夫有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说服了他原先的牺牲品

Josephus环的四种解法(约瑟夫环)

约瑟夫环 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列.通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解引用别人的一个图:直观说明问题 分析: 第一步:从1开始报数为3的时候就删除3号结点第二步:从4号结点开始报数,当为3的时候删除6号结点:第三步:从7号结点开始报数,当为3的时候

约瑟夫环问题--递推解法

利用数学推导,如果能得出一个通式,就可以利用递归.循环等手段解决.下面给出推导的过程: (1)第一个被删除的数为 (m - 1) % n. (2)假设第二轮的开始数字为k,那么这n - 1个数构成的约瑟夫环为k, k + 1, k + 2, k +3, .....,k - 3, k - 2.做一个简单的映射. k         ----->  0              k+1    ------> 1              k+2    ------> 2           

约瑟夫环问题python解法

约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人被杀掉:他的下一个人又从1开始报数,数到k的那个人又被杀掉:依此规律重复下去,直到圆桌周围的人只剩最后一个. 思路是:当k是1的时候,存活的是最后一个人,当k>=2的时候,构造一个n个元素的循环链表,然后依次杀掉第k个人,留下的最后一个是可以存活的人.代码如下: class Node(): def __init__(self,value,next=None): self.valu

约瑟夫环问题的链表解法和数学解法(PHP)

约瑟夫环问题 一群猴子排成一圈,按1,2,-,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去-,如此不停的进行下去,直到最后只剩下一只猴子为止,那只猴子就叫做大王.要求编程模拟此过程,输入m.n,输出最后那个大王的编号. 链表解法 function king($n,$m){ $monky = range(1,$n); $i = 0; while(count($monky)>1){ $i+=1; $head = array_shift($mon

算法神马的,需要再加一个约瑟夫环问题

# 约瑟夫问题 不使用链表 纯计算方式得到:# 第一种方法的实现,只能从头开始报数,没有办法随机指定从什么位置开始# 如果只用YsfTest 可以用传 n 的方式 来求出第几轮被pop掉的序号 # 约瑟夫环的第一种实现:def YsfTest(count,doom,n): if n ==1: temp = (count + doom - 1)%count return temp else: temp = (YsfTest(count - 1,doom,n - 1)+doom)%count ret