【算法】约瑟夫环问题解析与实现

一、导言

约瑟夫环(Josephus Problem)是一个经典的数学问题,涉及一个编号为 1 到 n 的人围成一圈,从第一个人开始报数,报到某个数字 m 的人出列,然后再从下一个人开始报数,如此循环,直到所有人都出列。本篇博客将详细解析约瑟夫环问题,并使用 Python 实现算法。

二、问题分析

在约瑟夫环问题中,有两个变量需要确定:人数 n 和报数的数字 m。当给定 n 和 m 后,需要确定最后留下的人的编号。例如,当 n=7,m=3 时,约瑟夫环问题的过程如下:

  • 1 2 3 4 5 6 7 (初始状态)
  • 1 2 4 5 6 7(第3个人出列,报数到3)
  • 1 2 4 5 7(第6个人出列,报数到3)
  • 1 4 5 7(第2个人出列,报数到3)
  • 1 4 5(第7个人出列,报数到3)
  • 1 4(第5个人出列,报数到3)
  • 4(第1个人出列,报数到3)

因此,最后留下的人的编号为 4。

三、解决方案

解决约瑟夫环问题的一种常见思路是使用循环链表。首先,我们可以创建一个循环链表,并将人的编号作为节点的值。然后,从第一个节点开始,依次报数,当报数到达 m 时,移除当前节点,继续下一个节点,直到只剩下一个节点为止。

下面是使用 Python 实现约瑟夫环问题的代码:

"""
定义单向链表节点类
"""
class Node:def __init__(self, value):# 节点的值self.value = value# 指向下一个节点self.next = Noneclass CircularLinkedList:def __init__(self):self.head = Nonedef append(self, value):"""append: 在链表末尾添加一个新节点,如果链表为空,则将头节点指向新节点,新节点的 next 指针指向头节点,否则遍历链表找到尾节点并将其 next 指向新节点,同时新节点的 next 指针指向头节点,以形成循环:param value::return:"""new_node = Node(value)if not self.head:self.head = new_nodeself.head.next = self.headelse:current = self.head# 循环找到最后一个节点while current.next != self.head:current = current.nextcurrent.next = new_nodenew_node.next = self.headdef remove(self, value):"""从链表中移除一个值为 value 的节点遍历链表找到要移除的节点,并将其前一个节点的 next 指针跳过该节点,实现移除操作。:param value::return:"""if not self.head:# 头节点为空执行# 如果链表为空,则结束方法returncurrent = self.headprev = Nonewhile True:if current.value == value:if current == self.head:temp = self.headwhile temp.next != self.head:temp = temp.nexttemp.next = self.head.nextself.head = self.head.nextelse:prev.next = current.nextbreakprev = currentcurrent = current.nextif current == self.head:breakdef get_survivor(self, m):"""根据约瑟夫环问题,找到最后留下的人的编号,其中参数 m 表示每次移除第 m 个人。使用循环遍历链表,每次移除第 m 个节点,直到只剩下一个节点为止,返回该节点的值。:param m::return:"""current = self.headwhile current.next != current:count = 1while count != m:current = current.nextcount += 1self.remove(current.value)current = current.nextreturn current.valuedef josephus(n, m):linked_list = CircularLinkedList()for i in range(1, n+1):linked_list.append(i)return linked_list.get_survivor(m)if __name__ == '__main__':n = 5m = 2survivor = josephus(n, m)print(f"The survivor's number is: {survivor}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/691951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

挑战杯 基于RSSI的室内wifi定位系统

0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 wifi室内定位系统 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:…

从零学算法300

300.给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。 示例 1&…

2月20日,每日信息差

第一、中国联通 1 月智慧客服客户问题解决率为 97.9%,大联接用户达 10.02 亿户,5G 套餐用户约 2.64 亿户,物联网终端连接约 5.06 亿户。5G 行业虚拟专网服务客户数为 9185 个,智慧客服问题解决率 97.9%,智能服务占比 8…

仿照elementUI写个步骤条

效果图如下&#xff1a; 直接上代码&#xff1a; <template><div class""><div class"steps"><div class"step" v-for"(step, index) in steps" :key"index"><divclass"icon"click&…

深度学习发展的艺术

将人类直觉和相关数学见解结合后&#xff0c;经过大量研究试错后的结晶&#xff0c;产生了一些成功的深度学习模型。 深度学习模型的进展是理论研究与实践经验相结合的产物。科学家和工程师们借鉴了人类大脑神经元工作原理的基本直觉&#xff0c;并将这种生物学灵感转化为数学模…

微信小程序如何配置服务器域名

要在微信小程序中配置服务器域名&#xff0c;您需要按照以下步骤进行操作&#xff1a; 登录微信公众平台&#xff08;https://mp.weixin.qq.com/&#xff09;。进入小程序管理后台。在左侧菜单中选择"开发"&#xff0c;然后选择"开发设置"。在"服务器…

公司有多个域名,是不是每个域名都安装一个SSL证书?

公司有多个域名&#xff0c;是不是每个域名都安装一个SSL证书&#xff1f; 拥有多个域名可能意味着会增加管理的复杂性和维护成本。如果您的公司有很多个域名&#xff0c;并不是每个域名都要逐个安装SSL证书。可以考虑购买多域名SSL证书或通配符SSL证书&#xff0c;而不是为每…

【Java】上传图片至阿里云oss服务器,文件上传以及图片base64上传

目录 引入maven依赖编写ossUtil编写Controller使用接口工具进行测试测试表单文件上传测试base64文件上传 首先需要在阿里云上开通oss服务&#xff0c;并获取到以下四个信息 endpoint: 购买的服务器节点地址accessKeyId: 接入的keyIdaccessKeySecret: 接入的key秘钥bucketName&…

[计算机网络]---UDP协议

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、端口号…

MyBatis数据库查询

文章目录 什么是MyBatisMyBatis程序的创建MyBatis实现数据库查询传参查询插入实现添加操作获取自增ID删除实现修改实现#{}和${}SQL注入 like查询 resultMap和resultType多表查询 对于普遍的后端开发而言&#xff0c;其程序主要包含了后端主程序和数据库两个部分&#xff0c;用户…

C/C++ BM11 链表相加(二)

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 总结 前言 这道题使用链表来实现加法运算&#xff0c;主要是涉及到数据对位以及加法进位的处理。 题目 假设链表中每一个节点的值都在 0 - 9 之间&#xff0c;那么链表整体就可以代表一个整数。 给定两个这种链表&#xff0…

使用C# Net6连接国产达梦数据库记录

达梦官网&#xff1a;http://www.dameng.com/ 1 下载达梦并进行安装 下载地址&#xff1a;官网首页——服务与合作——下载中心&#xff08;https://www.dameng.com/list_103.html&#xff09; 根据需要自行下载需要的版本&#xff0c;测试版本为&#xff1a;x86 win64 DM8版…

微信商户平台:如何查看超级管理员

如果有普通员工身份&#xff0c;可以登录 https://pay.weixin.qq.com/index.php/core/account/info 扫码进入后&#xff0c;进入菜单&#xff1a;账户中心》商户信息&#xff0c; 即可看到超级管理员的信息。

Windows 重启 explorer 的正确做法

目录 一、关于 Restart Manager 二、重启管理器实例 三、完整实现代码和测试 本文属于原创文章&#xff0c;转载请注明出处&#xff1a; https://blog.csdn.net/qq_59075481/article/details/136179191。 我们往往使用 TerminateProcess 并传入 PID 和特殊结束代码 1 或者…

VsCode指定插件安装目录

VsCode指定插件安装目录 VsCode安装的默认目录是在用户目录(%HomePath%)下的.vscode文件夹下的extensions目录下&#xff0c;随着安装插件越来越多会占用大量C盘空间。 指定VsCode的插件目录 Vscode安装目录&#xff1a; D:\Microsoft VS Code\Code.exeVscode插件安装目录&a…

算法沉淀——递归(leetcode真题剖析)

算法沉淀——递归 01.汉诺塔问题02.合并两个有序链表03.反转链表04.两两交换链表中的节点05.Pow(x, n) 递归是一种通过调用自身的方式来解决问题的算法。在递归算法中&#xff0c;问题被分解为更小的相似子问题&#xff0c;然后通过对这些子问题的解进行组合来解决原始问题。递…

firewall防火墙配置实战

基本操作 服务启停操作 #停止firewall systemctl stop firewalld #禁止firewall开机启动 systemctl disable firewalld #开启firewall systemctl start firewalld #开机启动防火墙 systemctl enable firewalld # 查看防火墙状态 firewall-cmd --state systemctl status f…

springboot文件上传需要的配置

总结一下文件上传需要的配置信息&#xff1a; ①在springboot的配置文件中指定请求大小及文件大小&#xff0c;默认大小较小&#xff0c;可能不够 spring.servlet.multipart.max-file-size512MB spring.servlet.multipart.max-request-size512MB ②在springboot的配置文件中…

实现VLAN间通信以太网链路聚合与交换机堆叠、集群华为ICT网络赛道

10.实现VLAN间通信 10.1.使用路由器实现VLAN间通信 使用路由器物理接口 路由器三层接口作为网关&#xff0c;转发本网段前往其它网段的流量。 路由器三层接口无法处理携带VLAN Tag的数据帧&#xff0c;因此交换机上联路由器的接口需配置为Access. 路由器的一个物理接口作为一…

easyx devc++ 开发具有导出文件夹DLC的瓦片地图编辑器

1. F1保存为 DLC 输出为当前文件目录下。 2. 瓦片的边框利用绘制到 -1 -1 把边框绘制到外部 3. 利用 1 实现网格保留 #include <graphics.h> #include <stdio.h> #include <string.h> #include <io.h> // 保存游戏地图贴图数据 void savegamemap(in…