约瑟夫问题 -- python实现

问题描述

N个人围成一个圈, 从第一个人开始报数, 报到M的人出圈, 剩下的人继续从1开始报数, 报到M的人出圈;如此往复, 直到所有人出圈.

列表解决

def solution_list(n, m):
    """
    初始化一个长度为n的列表, 默认值为True. 当某个元素出圈时, 将其置为False.
    循环迭代这个列表, 遇到值为False的元素则跳过, 当列表中全为False时表示所有人
    都已出圈.
    """
    # 初始化列表
    people = []
    for _ in range(n):
        people.append(True)

    result = []
    num = 1
    while any(people):
        for index, p in enumerate(people):
            if p:
                if num == m:                  # 出圈操作
                    people[index] = False
                    result.append(index + 1)
                    num = 1
                else:
                    num += 1
    print(‘-‘ * 25)
    print(f‘\n总人数为{n}, 报数为{m}‘)
    print(f‘约瑟夫序列为:\n {result}\n‘)
    print(‘-‘ * 25)
def solution_list2(n, m):
    """
    这是上面这种思路的另一种解法, 将圈内和圈外表示成0和1.
    这里实现循环迭代的方式我第一次遇到, 记录一下
    """
    people = [0 for _ in range(n)]

    alive = n                           # 剩余人数
    index = 0
    num = 0                             # 计数器, 当index == m时出圈
    result = []

    while alive > 0:
        num += 1 - people[index]        # 每轮到一个人报数, 不论0或1都进行计数
        if num == m:
            result.append(index + 1)    # 出圈
            people[index] = 1           # 将出圈人置为 1
            alive -= 1                  # 剩余人数 - 1
            num = 0                     # 重置计数器

        # 与总人数 n 取余, 可以实现index在 0 ~ count -1之间一直循环, 达到循环迭代的目的
        index = (index + 1) % n

    print(‘-‘ * 25)
    print(f‘\n总人数为{n}, 报数为{m}‘)
    print(f‘约瑟夫序列为:\n {result}\n‘)
    print(‘-‘ * 25)

循环链表解决

class Node:
    """节点"""
    def __init__(self, value):
        self.data = value
        self.next = None

    def __repr__(self):
        return f‘Node: {self.data}‘

class CircularLinkedList:
    """循环链表"""
    def __init__(self):
        self.rear = None    # 尾节点

    def is_empty(self):
        return self.rear is None

    def append(self, elem):
        """尾插法"""
        temp = Node(elem)
        if self.rear is None:
            temp.next = temp
            self.rear = temp
        else:
            temp.next = self.rear.next
            self.rear.next = temp
            self.rear = temp

def solution_circular_linked_list(n, m):
    """
    通过循环链表解决, 每次出圈弹出该节点
    """
    clist = CircularLinkedList()
    for i in range(n):
        clist.append(i + 1)

    result = []
    pre = clist.rear                    # 当前节点的上一个节点
    cur = clist.rear.next               # 当前节点
    num = 0                             # 计数器

    while cur.next is not cur:
        num += 1
        if num == m:                    # 出圈
            result.append(cur.data)
            pre.next = cur.next         # 弹出当前节点
            num = 0                     # 重置计数器
        else:
            pre = pre.next
        cur = cur.next
    result.append(cur.data)

    print(‘-‘ * 25)
    print(f‘\n总人数为{n}, 报数为{m}‘)
    print(f‘约瑟夫序列为:\n {result}\n‘)
    print(‘-‘ * 25)

参考:
经典算法--约瑟夫环问题的三种解法
百度百科

原文地址:https://www.cnblogs.com/thunderLL/p/12072059.html

时间: 2024-07-31 21:45:40

约瑟夫问题 -- python实现的相关文章

10行python代码实现约瑟夫问题

什么是约瑟夫问题? 约瑟夫问题是一个有趣的数学游戏,游戏规则如下: 1.N个人围成一个圈,编号从1开始,依次到N. 2.编号为M的游戏参与者开始报数,报数从1开始,后面的人报数接龙,直到K为止,报数为K的人将出局. 3.出局者的下一个玩家接着从1开始报数,如此循环,直到剩下一个玩家时游戏结束,这个玩家就是游戏获胜者. 那么问题来了,哪个编号是游戏获胜者呢? 下面通过简单的几行python代码来解决这个问题: #!/usr/bin/env python # Joseph Problem def j

约瑟夫环问题及python与c++实现效率对比

约瑟夫环是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列. python实现: # 单链表节点 class LinkNode: def __init__( self, value ): self.value = value self.next = None # 创建循环单链表,值从1开始 def create_cycle(

以迭代的方式用Python解决约瑟夫问题

2017年1月16日22:43:21 昨天,学习鱼C的链表时看到一个约瑟夫问题: 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而Josephus 和他的朋友并不想遵从.首先从一个人开始,越过k-2个人(因为第一个人已经被越

10行Python代码解决约瑟夫环(模拟)

http://blog.csdn.net/dengyaolongacmblog/article/details/39208675 1 #!/usr/bin/env python 2 # coding: utf-8 3 4 import os 5 import sys 6 import string 7 import operator 8 import re 9 10 def josephus(n,k): 11 link=range(1,n+1) 12 ind=0 13 for loop_i in

约瑟夫环问题python解法

约瑟夫环问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到k的那个人被杀掉:他的下一个人又从1开始报数,数到k的那个人又被杀掉:依此规律重复下去,直到圆桌周围的人只剩最后一个. 思路是:当k是1的时候,存活的是最后一个人,当k>=2的时候,构造一个n个元素的循环链表,然后依次杀掉第k个人,留下的最后一个是可以存活的人.代码如下: class Node(): def __init__(self,value,next=None): self.valu

Python 约瑟夫圈问题

需求:有n个人围成一圈,顺序排号, 从第1个人开始报数(从1到3),凡报到3的人退出圈子,问最后留下的是原来第几号的那位 代码逻辑 n个人,通过输入参数n,生成一个长度为n的列表 通过报数逻辑函数,只要数到3的就把那个位置相对应的列表值设置为0,同时留下的人数也要减1,直到剩下的人数为1,才退出循环 通过报数逻辑函数,最后得到新的列表(只有一个值是1,其余都是0),进行循环即可 代码如下: 1 #coding:utf-8 2 #__author__ = 'Diva' 3 # 用户输入n,n代表人

算法系列:约瑟夫斯问题

约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环. 有{\displaystyle n}个囚犯站成一个圆圈,准备处决.首先从一个人开始,越过{\displaystyle k-2}个人(因为第一个人已经被越过),并杀掉第k个人.接着,再越过{\displaystyle k-1}个人,并杀掉第k个人.这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着. 问题是,给定了{\displaystyle n}和{

约瑟环的python实现(举例说明)

 N个人围成一圈报数,报到某一个数m的就出局,问你最后剩下来的人的号码? 网上通用约瑟夫环的算法是: //函数接收n和m,返回最后出圈的是第几个人 /*e.g.       yuesefu(5,2)=3                   yuesefu(2,100)=1*/ int   yuesefu(int   n,int   m) {         int   i,r=0;         for   (i=2;i <=n;i++)   r=(r+m)%i;         return

python解约瑟夫环问题

故事: 约瑟夫问题(Josephus Problem)据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止.然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于