什么是约瑟夫环(百度百科)
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后 [1] 结果+1即为原问题的解。
我的思路 (python实现)
- 有一个长度为 n 的队伍(list)
- 每次找出第k个位置的人(k为每次查找的位置)
- 找出后利用 python的列表切割
- 这时候就有俩个列表暂且称左边的列表为 left 右边为right
- 这时候,以right列表为头,left列表为尾 list = right+left
- 依次循环 不停取k个位置的值,然后不停的列表切割
##代码实现
while True:
del(item[kill_numbers - 1])
#python 列表删除方法 通过位置删除
#至于为什么删除的是 k-1 应该都知道吧 list是从0 开始计数的
left = item[0:kill_numbers - 1]
right = item[kill_numbers - 1:]
item = right + left
- 光这样是还不够的
- 如果 k 的值大于了list的长度不就抛错了吗
- 这时候我们需要做特殊处理(当k的值比超出了list的长度了)
- 那我们脑子中想的就是让list变长,长度变到比k的值要大
- 新建一个 list (代码中是item2)来存放增长的目标
- 通过while循环直到item2 的长度 大于等于 k (kill_numbers)break循环
- the_kill是第k个位置的值 通过这个方法找到 我们的所要选出 新 list中位置为k 所对应的值 the_kill
##代码实现
def out_list_length(item, kill_numbers):
item2 = []
while item.__len__() < kill_numbers:
item2 += item
if item2.__len__() >= kill_numbers:
break
the_kill = item2[kill_numbers - 1]
return the_kill
- 接下来我们要做的
- 就是在原来的list中删除那个值为the_kill的目标
##代码实现
the_kill = out_list_length(item, kill_numbers)
item.remove(the_kill)
# remove list内容移除的方法 通过值移除
—————————-分割线———————————————
完整代码
item = []
total_people = 300 # 容器 比方说这场游戏的总人数
kill_numbers = 18 # 出列序号 比方说你要第几个人死
left_numbers = 10 # 最后剩余数量 比方说你要几个人活
for num in range(total_people):
item.append(num + 1)
def out_list_length(item, kill_numbers):
item2 = []
while item.__len__() < kill_numbers:
item2 += item
if item2.__len__() >= kill_numbers:
break
the_kill = item2[kill_numbers - 1]
return the_kill
kill_list = []
while True:
if item.__len__() >= kill_numbers:
kill_list.append(item[kill_numbers - 1])
del (item[kill_numbers - 1])
left = item[0:kill_numbers - 1]
right = item[kill_numbers - 1:]
item = right + left
if item.__len__() == left_numbers:
break
if item.__len__() < kill_numbers:
the_kill = out_list_length(item, kill_numbers)
kill_list.append(the_kill)
item.remove(the_kill)
left_list = item
print('被神制裁的人:',kill_list)
print('活下来的人:',left_list)