约瑟夫环问题

约瑟夫环问题

本文档基于简单的python知识来解决约瑟夫环问题

一、问题描述

故事版本较多,看起来略有不同,但实际上是殊途同归,问题本质都是一样的。本次研究主要针对其中一种故事版本。故事内容如下:

罗马帝国时期,犹太士兵被罗马人包围,为了不当俘虏,决定集体自杀。自杀的方式是所有人围成一个圈,第一个士兵杀掉他左边的第二个士兵,第三个士兵杀掉第四个士兵,第五个士兵杀掉第六个士兵。以此类推,直到最后只剩下一个人,然后他在自杀。
在这群犹太士兵里面,有个叫约瑟夫的人,他想投降保命,那么他应该站在什么位置,才能成为最后一个剩下的人,这样就可以不用自杀,直接投降。

二、问题解析

军队人数未知,可以自定义。

首先把问题减化,我只考虑前三个人的情况,后面他们怎么杀,我不关心。
我只看前三个人。首先可以确定的是,第一个人会杀死第二个人。

也就是说,无论是谁,只要站在第二个位置上,就必须死。这是解决问题的关键。

那么既然第一个人已经杀了一个了。他现在可以歇一会,给我滚回到队尾,去当最后一个人。

然后现在重新排序,刚刚第三个人,晋升到第一的位置了。刚刚第四个人晋升到第二的位置了。
所以新序列的第一个人就要把第二个给杀死,然后他也得滚回队尾,休息着。

以此类推,第一个人杀第二个,第二个出局,第一个去到队尾。然后重新排序。
继续由第一个人杀第二个,最后杀掉只剩下一个人,就结束了

三、python实现

#约瑟夫环问题
'''
问题分析
1、假设总共n个人,给1-n,这n个人进行编号,存储在一个列表中
2、从列表起始位置开始数数,数到第2个人,把他踢出去
3、把第1个人移到列表末尾,形成一个新的列表,新列表的第1个人,其实就是上一个列表的第3个人
4、继续重复步骤2和3,直到剩余人数为1,输出此时新列表第1个人对应编号
'''

def fun(man):                        #定义fun()函数
    lst=[i for i in range(1,man+1)]  #根据总人数生成列表[1,2,3......n]
    #print(lst)
    if man==1 or man==2:             #总人数为1或者2,直接判定第一个人存活
        print('幸存者为:',lst[0],'号')
    else:
        a=man  #定义a为剩余人数
        while a>1:     
            lst.append(lst[0])        #在列表末尾添加第一个人
            lst.pop(1)                #删除列表第二个人
            lst.pop(0)                #删除列表第一个人
            a=a-1                     #人数减少1
        print('幸存者为:',lst[0],'号')
    
#输入总人数(总人数是大于等于1的正整数)
man=int(input('请输入总人数:'))
fun(man)

四、总结

假如总人数是100,运行程序,输入总人数:100,得到生存的位置是:73号

使用上面的程序,无论人数多少,总能求出生存的位置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值