约瑟夫环

简介: 【10月更文挑战第11天】

一、约瑟夫环问题介绍


def josephus(n, m):
    people = list(range(1, n + 1))
    index = 0
    while len(people) > 1:
        index = (index + m - 1) % len(people)
        eliminated_person = people.pop(index)
        print(f"淘汰的人是:{eliminated_person}")
    return people[0]

n = 8  # 总人数
m = 3  # 每次报到 m 的人被淘汰
last_person = josephus(n, m)
print(f"最后剩下的人是:{last_person}")

约瑟夫环问题是一个经典的数学问题。问题描述通常为:n 个人围成一圈,从第一个人开始报数,每次报到 m 的人将被淘汰,如此循环,直到最后只剩下一个人。

二、理解方式

  1. 形象化理解

    • 可以想象成 n 个小朋友围成一圈玩游戏。有一个裁判从第一个小朋友开始数数,每数到 m,那个小朋友就被要求离开圈子。然后继续从下一个小朋友开始数数,重复这个过程,直到只剩下一个小朋友。
    • 例如有 7 个人,从 1 开始报数,每次报到 3 的人被淘汰。第一轮,第 3 个人被淘汰;第二轮,第 6 个人被淘汰;第三轮,第 2 个人被淘汰;第四轮,第 7 个人被淘汰;第五轮,第 5 个人被淘汰;第六轮,第 1 个人被淘汰;最后剩下第 4 个人。
  2. 数学角度理解

    • 可以通过数学推导来分析问题。假设编号从 0 开始,对于 n 个人,第一次淘汰的是 (m - 1)%n 位置的人。然后剩下 n - 1 个人,此时从被淘汰的下一个人开始重新编号,原来的编号为 k 的人在新编号体系下变为 (k - (m - 1)%n)%n。这样不断递归下去,直到只剩下一个人。

三、推测最后一人的方法

  1. 模拟法

    • 就像前面给出的代码那样,通过模拟整个淘汰过程,逐步淘汰人,直到只剩下最后一个人。这种方法直观易懂,但对于较大的 n 和 m 可能效率较低。
    • 每次淘汰一个人后,更新剩余人的编号和总数,不断重复这个过程,直到只剩下一个人。
  2. 数学推导法

    • 利用递推公式可以逐步计算出最后一个人的编号。对于有 n 个人,每次数到 m 淘汰一个人,设 f(n,m)表示最后剩下的人的编号,则有递推公式:f(n,m)=(f(n-1,m)+m)%n,其中 f(1,m)=0。通过从 f(2,m)开始逐步计算到 f(n,m),就可以得到最后一个人的编号。
    • 例如当 n = 7,m = 3 时,f(2,3)=(f(1,3)+3)%2 = 1;f(3,3)=(f(2,3)+3)%3 = 1;f(4,3)=(f(3,3)+3)%4 = 0;f(5,3)=(f(4,3)+3)%5 = 3;f(6,3)=(f(5,3)+3)%6 = 0;f(7,3)=(f(6,3)+3)%7 = 4。所以最后剩下的人的编号是 4。
目录
相关文章
|
2月前
约瑟夫环问题
约瑟夫环
27 0
约瑟夫环问题的几种解法
约瑟夫环问题的几种解法
109 0
|
算法
约瑟夫环问题(三种方法)
约瑟夫环问题(三种方法)
151 0
|
Java
(五)Java数据结构之循环链表解决约瑟夫(Josephus)环问题
(五)Java数据结构之循环链表解决约瑟夫(Josephus)环问题
111 0
|
算法 索引 Python
细究“约瑟夫环”
细究“约瑟夫环”
101 0
约瑟夫环的解法
约瑟夫环的解法
129 0
约瑟夫环
题目: 已知n个人(以编号1,2,3--n分别表示)围坐在一张圆桌周围。从编号为1的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人有出列;以此规律重复下去,知道圆桌周围的人全部出列。输出出列顺序和最后剩下的人。
104 0

热门文章

最新文章