约瑟夫生者小游戏

阅读: 评论:0

约瑟夫生者小游戏

约瑟夫生者小游戏

30 个人在一条船上,超载,需要 15 人下船。于是人们排成一队,排队的位置即为他们的编号。报数,从 1 开始,数到 9 的人下船。如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?

s=list(range(1,31))  #用一个30个数的列表代表30个人
for i in s:if len(s)>15:    #列表长度>15,代表循环还没有终止print("第%d人下船了"%s[8]) #数到9的人,也就是s[8]s=s[9:]+s[:8]   #关键之处,用列表的切片重新形成列表
print(s)              #而且因为要重新开始,把s[9:]放到前面
#最后可以打印列表,看看还剩下哪些人

这里巧妙利用列表的切片操作,把一个人排除之后顺利连成新列表继续进行切片,直到达到要求的人数。

进一步我们把这个代码改到普遍一点。把总人数,要留下的人数,以及数到的这个数字分别用m,n,l代替。

m,n,l=map(int,input().split())
s=list(range(1,m+1))
for i in s:if len(s)>n:print("第%d人下船了"%s[l-1])s=s[l:]+s[:l-1]
print(s)

这样我们的代码就适用于更多的情况,只需要输入具体的数字就可以执行。
但是,运行有些情况时会出现bug。比如我们取m,n,l分别是30, 8,12。

30 8 12
第12人下船了
第24人下船了
第6人下船了
第19人下船了
第2人下船了
第16人下船了
第30人下船了
第15人下船了
第1人下船了
第18人下船了
第5人下船了
第23人下船了
第11人下船了
第3人下船了
第25人下船了
第17人下船了
第10人下船了
第8人下船了
第7人下船了
Traceback (most recent call last):File "<ipython-input-5-5667debe2e47>", line 1, in <module>runfile('C:/Users/lenovo/yuesefu.py', wdir='C:/Users/lenovo')File "E:anacondalibsite-packagesspyder_kernelscustomizespydercustomize.py", line 827, in runfileexecfile(filename, namespace)File "E:anacondalibsite-packagesspyder_kernelscustomizespydercustomize.py", line 110, in execfileexec(ad(), filename, 'exec'), namespace)File "C:/Users/lenovo/yuesefu.py", line 12, in <module>print("第%d人下船了"%s[l-1])IndexError: list index out of range

代码可以正确执行多次,但是后面会发生错误。

IndexError: list index out of range

这是列表索引越界 。仔细观察输出的部分,发现正好有19人下船了,我们要留下8个人,应该还有3个人要下去,但是每次报12的人要下去,也就是s[11],这时候列表只有11个人了,所以发生了列表索引越界。

代码只适用于 m > n > = l m>n>=l m>n>=l的情况。

为了更加普适,我们要避免使用列表导致的索引越界,于是有了下面的代码。

m,n,l=map(int,input().split())
people=[i for i in range(1,m+1)]#构建所有人的列表
while len(people)>n:#当人的个数超过要求时,就要进行操作i=1      #初始化i的值while i<l: #没有到第l个人的时候,将第一个数追加到列表末尾people.append(people.pop(0))i+=1print('{}下船了'.format(people.pop(0)))
print(people)

这里同样使用了列表操作,不同之处在于这里用append函数和pop函数模拟整个过程,使得只要这个元素不是所要的元素,这个列表就可以不断追加,不用担心是否越界的问题。这里的l甚至可以取大于m的数,依然满足。

改进版约瑟夫生者小游戏,适用于各种情况。 m > = n , l m>=n,l m>=n,l可以取任何正整数。

再次试验上面的例子,得到了正确的结果。

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

通常我们遇到的问题常常会问道最后只有一个人的情况,也就是n等于1的情况,这时候稍作改变即可。

m=int(input())
l=int(input())
people=[i for i in range(1,m+1)]#构建所有人的列表
while len(people)>1:#当人的个数超过要求时,就要进行操作i=1      #初始化i的值while i<l: #没有到第l个人的时候,将第一个数追加到列表末尾people.append(people.pop(0))i+=1people.pop(0)
print(people[0])

本文发布于:2024-01-31 03:47:59,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170664408225175.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:约瑟夫   小游戏
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23