I am a teacher!

导航

习题解析之:约瑟夫环问题

【问题描述】

据说著名历史学家 Josephus有过以下的故事:Josephus及他的朋友共41人围成一个圆圈,由第1个人开始报数,每数到3该人就必须出去,然后再由下一个人重新报数,直到圆圈上少于3人为止。Josephus 将朋友与自己安排在第16个与第31个位置,成为最后剩下的人。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬

扩展这个问题,当人数为n,每次报数为k时,求解最后的K-1个剩下的人的位置

输入格式‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬
在同一行内输入两个正整数n和k,要求k > = 2且n >= k

输出格式‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬
以列表形式显示剩余的人的序号。
如果k<2或者n<k,打印Data Error!

示例‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬
输入:
41 3

输出:
[16, 31]

‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬【编程思路】

        本题是典型的列表切分与拼接的应用。

        先用推导式  [x for x in range(1,n + 1)] 生成一个列表 ls,该列表中有 n 个元素,分别为 n 个人的序号。

        每次报数 k 的人出圈,即将列表元素 ls[k - 1] 从列表中删除,同时更新列表。由于参与报数的人围成一个圆圈,因此将出圈元素的后续元素放在列表的前面,出圈元素前面的元素接在列表的后面,以便下一次报数处理。即列表 ls = ls[k:] + ls[0:k - 1]。

        用循环 while len(ls) >= k: 来处理这个报数过程,直到列表中元素个数小于 k ,即得到最后的K-1个剩下的人的序号。
        编写的源程序如下:

        image

posted on 2025-11-28 14:21  aTeacher  阅读(0)  评论(0)    收藏  举报