python练习 - 约瑟夫环问题

586 阅读1分钟

前言

题目1:计算约瑟夫环问题

tips:《幸运的基督徒》 有15个基督徒和15个非基督徒在海上遇险,为了能让一部分人活下来不得不将其中15个人扔到海里面去,有个人想了个办法就是大家围成一个圈,由某个人开始从1报数,报到9的人就扔到海里面,他后面的人接着从1开始报数,报到9的人继续扔到海里面,直到扔掉15个人。由于上帝的保佑,15个基督徒都幸免于难,问这些人最开始是怎么站的,哪些位置是基督徒哪些位置是非基督徒。输出最后站位,用1表示是基督徒,0表示非基督徒;

模拟操作的第一种思路

给30人标上序号,1至30;每次取出排名第九的人

那么我们可以截取前8个人的序号放置最末尾去

IN

def ring(n):
    num = 0
    list1 = []
    for a in range(1,31):
          list1.append(a)
    # print(list1)
    while num < n :
        num+=1
        a = list1[:8]
        b = list1[9:]
        list1 = b+a
    print(list1)
    return list1
ring(15)

OUT

[25, 28, 29, 1, 2, 3, 4, 10, 11, 13, 14, 15, 17, 20, 21]

思路有了,代码优化一下:

IN

list1 = [i for i in range (1 , 31)]
# print(list1)
ls = []
while True:
    ls.append (list1[8])
    list1 = list1[9::] + list1[0:8:]
    # print(list1)
    if len (list1) == 15:
        break
        
print (ls)   
print(list1)

OUT

[9, 18, 27, 6, 16, 26, 7, 19, 30, 12, 24, 8, 22, 5, 23]
[25, 28, 29, 1, 2, 3, 4, 10, 11, 13, 14, 15, 17, 20, 21]

IN

list2 = []
a = 0
while a <30 :
    list2.append(0)
    a+=1
print(list2)
print(len(list2))

for i in list1:
    list2[i] = 1

list3 = ''.join(map(str,list2))
# print(''.join(map(str,list2)))
print(list3)

OUT

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
30
011110000011011101001100010011

模拟操作的第二种思路

逢9就删

每次到第九个数,重置计数且删除第九个数字

IN

list1 = [i for i in range (1,31)]

n = 1
a = 0
b = 15 
while len (list1) > b:
    if n == 9:
        n = 1
        
#         print (list1[a],end=',')
        list1.pop (a)
        
    else:
        n += 1
        a += 1
    if a == len (list1):
        a = 0
        
print(list1)

OUT

[1, 2, 3, 4, 10, 11, 13, 14, 15, 17, 20, 21, 25, 28, 29]