约瑟夫问题,过程推理,递归

约瑟夫环递归求解 约瑟夫环递归求解题目约瑟夫环是一个数学的应用问题:已知m个人(以编号1,2,3...m分别表示)围坐在一张圆桌周围。从编号1开始报数,每次报到k的那个人出列,然后下一个人再从1开始报数。 阅读详情

约瑟夫问题描述:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列,(来自百度百科)。一般题会让我们求出最后一个人几号;


先举一个简单的例子吧:  

                                                                           

如上图从1到10围城的圆圈,没个一个数去掉一个,问最后那个数被留了下来;

我们可以简单模拟一下期初先消去2,依次为:4,6,8,10,3,7,1,9,于是最后剩余了5号,


我们可以设T[n]表示当有n个数围城一个圈,最后剩余的那个数就是T[n],然后我们开始模拟,推理。

先把n(1...10)给推出来吧:

         

可以看出来T[n]总是奇数,因为我们在绕第一圈的时候就已经把所有的偶数给去掉了,不信自己可以模拟一番,

既然第一轮去掉的都是偶数,那么我们可以利用这个结论,假如我们假设有2n个数,经过第一轮去掉之后,那么毋庸置疑就只剩下奇数了,那么3号就是第二轮的第一个要去掉的。而T[2n]又可以由T[n]这个过程推出来,2n的第二轮开始的数就相当于n的第一轮开始的数的二倍减一,依次类推我们可以得出:T[2n]=2T[n]-1;

我们可以根据这个推论快速推出T[20]=  2*T[10]-1  =  2x5-1  =  9;


但是我们并没有推出更为简单的结果,并不满意,我们根据找出来的这个规律再写出多一点例子:


乍一看,这么多数哪有什么鬼规律,其实仔细一看还是有的,有一个递增(d=2)的循环节数列,为了容易分辨请看下表,每组循环节我用不同的颜色给标记了:


神奇吧,然后我们再来推论,T[n](n->+oo)的情况;

我们要推出这个循环节出现的情况,然后对应每个单独的循环节求值,就简单了。

然后我们开始讨论循环节,(这里说循环节可能不合适,但是我没有找到一个合适的词语形容,大家知道我要表达的意思就好,怪我才疏学浅),我们以n为例;

第一个循环节:1

第二个循环节:2,3

第三个循环节:4,5,6,7

第四个循环节:8,9,10,11,12,13,14,15

第五个循环节:16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31

.......


有没有发现,每个循环节都是以一个2的次方开始并且以一个2的次方减一结束,如:

第一个循环节是:[2^0,2^1),          (左闭右开哦)

第二个循环节是:[2^1,2^2),

第三个循环节是:[2^2,2^3),

......

第N个循环节是:[2^(N-1),2^N);


聪明的小伙伴想必现在已经有答案了,但是鄙人眼拙,还要做一下计算,回归一开始的T[n];

那么现在当n=6时,我们可以直接找到开始的循环节是4,所以n=6是在本循环节的m=(6-4+1)=3位,再用等差数列求和公式即:T[6]=   d*(m-1)+1   =2*2+1=5;

同样的当n=100时,我们可以立刻求出,实在64循环节的(100-64+1)=37位,然后T[100]=2*36+1=73;

然后一般式就是:   T[n] = 2*(n-m)+1;(m可由上述的n=100或者n=6的出)

注:m要根据n来定,可以存一个数组,因为2的32次方已经超大了,所以不会影响时间复杂度;


那么现在这个问题已经解决了,但是关于这个问题还有一个更加神奇的推广(我从一本神奇的书上看到过),有兴趣的小伙伴可以继续往下看:

在求解的过程中,我们发现2的幂起了很重要的作用,所以自然要来研究n和T[n]的以2为基数的表示即二进制。


然后经过一系列的转化......具体的过程我忘了,我只记住了结果,就是n的二进制,最高位的那个数放到最低位,比如n=6时,n=(110)
₂,然后我们把最高位放到最后得n=(101)₂,然后再算二进制,1*2^2 + 0*2^1 + 1*2^0 = 5;

显然答案是对的,再举个例子吧,当n100时,n=(1100100)₂,然后最高位的1放在最后得:n  =  (1001001)₂;

最后结果经过计算得:64+8+1  =  73;   可以证明答案是对的,所以我们可以套上面的公式,也可以用二进制的方法求解;


也许你对上面的解释有疑问,就是为什么要把二进制的最高位放在最后呢,这个我也没法对你做出正规的解释,但是我又找到了另一个不改变最高位的方法,还拿n=6时为例吧,n=(110)₂ = 1*2^2 + 1*2^1 - 1*2^0 = 4 + 2 - 1 = 5;

再如:n=100时,n=(1100100)₂=2^6 + 2^5 - 2^4 - 2^3 + 2^2 - 2^1 - 2^0 =64+32-16-8+4-2-1 = 73;

这个结果是对的,也不需要进行二进制最高位的转换,所以我们可以得出T[n]结果就是n的对应二进制,位为1就加位为0就减,这个结果就很容易算出来了,虽然很神奇,但是我还是比较喜欢我的推出来的那个解法;


当然我相信约瑟夫还有后续,还有很长的路,但是我不能就此止步,去学更多新知识了;

C语言 约瑟夫环问题 约瑟夫环问题描述: 每一个结点有两个数据域和一个指针域,数据域分别存储为id和password,指针域指向下一个结点(图1-1); 解决问题: 由键盘输入人数和初始密码。 根据输入的人数创建不带头结点(带头结点的链表也可以)的单向循环链表。 提示输入每一个人的密码(每一个id对应唯一一个password)。 输出id和password。 根据输入的初始密码fir... 阅读详情

相关推荐

嵌入式设备系统日志记录及调试技巧_嵌入式日志系统(1),如何成为杰出的程序员

这里面我使用的芯片为哈弗体系,全局常量存储编译器默认分配在flash,需要注意如果使用片内flash时,注意存储调试等级的flash块不要与代码区重合,要不然修改调试等级擦除flash块同时PC指针指向当前块的代码区,会导致仪器死机;这个也是之前用的比较多的,以上代码是模仿linux 内核的写法,可以比较好的做到日志信息分层,编译时相加对应的编译开关即可。但有个弊端就是,切换debug等级时,需要重新编译且需更新固件,而嵌入式设备出现异常后更新固件往往复位后,故障有时很难复现,调试起来比较浪费时间。

2401_84240431的博客 1294

约瑟夫问题

  约瑟夫问题 作者:Ackarlix      这是一个非常经典的问题:n个骑士编号1,2,...,n,围坐在圆桌旁,编号为k的骑士从1开始报数,报到m的骑士出列,然后下一个位置再从1开始报数,找出最后留在圆桌旁的骑士编号。    这个问题可以用没有头结点的循环链表解决,数据域存放骑士的编号,出列的骑士,删除其对应的结点,最后剩下的那个结点就是问题所求的骑士编号。程序

Ackarlix的专栏 2759

创客学院嵌入式驱动开发——学习资料汇总

1.创客学院知识巩固-01C语言回顾_C/C++_Set_Mode的博客-优快云博客https://blog.youkuaiyun.com/Set_Mode/article/details/94431050 2.创客学院知识巩固-02数据结构_Set_Mode的博客-优快云博客https://blog.youkuaiyun.com/Set_Mode/article/details/94431087 3.创客学院知...

snaking616 5117

约瑟夫问题(数组+队列+公式迭代+递归)

约瑟夫问题(数组+队列+公式迭代+递归) 约瑟夫环问题起源于一个犹太故事: 罗马人攻占了桥塔帕特,41个人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友。剩余的39个人为了表示不向罗马人屈服,决定集体自杀。大家制定了一个自杀方案,所有这41个人围成一个圆圈,由第一个人开始顺时针报数,每报数为3的人就立刻自杀,然后再由下一个人重新开始报数,仍然是每报数为3的人就立刻自杀……,直到所有的人都自杀身亡为止。约瑟夫和他的朋友并不想自杀,于是约瑟夫想到了一个计策,他们

qq_51297987的博客 3461

excel 利用SUBTOTAL函数计算筛选后数列总和、均值、最大、最小值

表里有三个人,咱们需要筛选出三个人,并分别计算他们的总和值。 先看一下数据范围(A1:B27) 通过筛选找张三。 按照上图所示输入函数,选择9,求和。 然后按照函数输入即可。 就能计算出结果。 筛选项选择王五,就会自动计算王五的总和。 筛选到李四就会自动计算李四的总和。 如果把9改成1,就是自动计算筛选出来的均值结果,如下图所示。 如果改成4就是取筛选项的最大值,选择5就是取最小值。 ...

yuanYW7556的博客 3万+

[DA45] 使用PageRank算法分析希拉里邮件中的人物关系

一. 相关知识 (一) PageRank算法 PageRank 算法是 google 公司的创始人拉里·佩奇和谢尔·盖布林于1998年提出的网页搜索优化算法. 详细内容请见百度百科:google pagerank. 如果你了解了该算法, 就能明白上一段的超链接从本页面链出, 链入百度百科的 PageRank 算法页面增加了该页面...

Vincent_Chu的博客 2378

C++约瑟夫问题求解

约瑟夫问题:n个骑士编号1,2,…,n,围坐在圆桌旁。编号为1的骑士从1开始报数,报到m的骑士出列,然后下一个位置再从1开始报数,找出最后留在圆桌旁的骑士编号。 (1)编写一个函数模板。以一种顺序容器的类型作为模板参数,在模板中使用指定类型的顺序容器求解约瑟夫问题。m,n是该函数模板的形参。 程序参考的输入(数字前为提示文字): Input n and m:7 3 程...

Cosmopolitan的博客 7909

Android14 Qcom 从Framework到Driver带你连接WIFI(一)

前面已经讲完了WIFI打开的流程,那么通过UI这时候是可以选择需要连接的网络进行连接。从这里开始我们看连接的流程。

IAYLBL的博客 696

约瑟夫问题_公式原理详解

每次增加一个人,我们第一轮的报数被指定的必定是新加入的人。

小黯 3万+

x2-DFD:A framework for explainable and explainable deepfake detection

该文章提出了X2-DFD框架,用于可解释和可扩展的深度伪造检测。通过评估大型多模态语言模型(MLLMs)在深度伪造检测中的内在能力,发现它们在不同伪造相关特征上的有效性各异。基于此,实施了针对性的微调策略,显著提高了MLLMs的解释能力,并整合了外部深度伪造检测器(EDDs),以结合MLLMs和传统检测器的互补优势,实现更好的检测和解释。

志在山顶的人,不会贪念山腰的风景 510

Dify使用教程3:Dify创建工作流

Dify使用教程3:Dify创建工作流 接着,我们连接下一个节点:“LLM”填入上下文变量为:result。这时候知识库就添加成功了。添加新节点:结束节点。

拥抱具身智能,昇腾Ascend C 5129

C语言丨约瑟夫问题(约瑟夫环)

约瑟夫问题又称为约瑟夫环,约瑟夫问题有很多变种。本文就以几个经典的约瑟夫问题介绍其几种解法。

weixin_60921752的博客 3万+

【笔记篇】Davinci Configurator EcuM模块

autosar ecum模块简介

weixin_47571898的博客 1269

约瑟夫环问题

目录1 题目描述1.1 例题2 题解2.1 链表法2.2 推理法2.2.1 递归法2.2.2 循环迭代法 1 题目描述 先来看这个类型的某个题目描述: 约瑟夫生者死者游戏 约瑟夫游戏的大意:30个游客同乘一条船,因为严重超载, 加上风浪大作,危险万分。因此船长告诉乘客,只有将全船 一半的旅客投入海中,其余人才能幸免于难。无奈,大家只 得同意这种办法,并议定30 个人围成一圈,由第一个人数起,依次报数,数到第9人,便把他投入大海中,然后再从 他的下一个人数起,数到第9人,再将他投入大海中,如此 循环地进行,直

weixin_45798469的博客 234

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

约瑟夫环问题详解(图文结合)--C语言

目录 约瑟夫小故事: 问题数学化: 特殊情况: 1. q = 2 ,n = (k=1 , 2, 3, ......) 2. q = 2 ,n =​+ t (k=1 , 2, 3, ......) 一般情况: 思路总结: 算法推导: 代码实现: 总结: 约瑟夫小故事: 约瑟夫是犹太军队的一个将军,在反抗罗马的起义中,他所率领的军队被击溃,只剩下残余的部队40余人,他们都是宁死不屈的人,所以不愿投降做叛徒。一群人表决说要死,...

qq_63412763的博客 7518

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数据结构与算法-约瑟夫问题

约瑟夫问题起源于犹太人的传统故事,讲述了一群人在围成一圈玩游戏,按照一定规则顺次报数并淘汰出局,直至只剩一人。n个人站成一圈,从某人开始顺时针或逆时针报数(编号从1开始)。每报到某个特定数值m的人将被淘汰出圈,然后从下一个人重新开始报数。重复此过程,直至圈子中只剩一人,这个人就是胜者。

m0_62988332的博客 1836

【C++】约瑟夫环问题:深度解析与高级优化

约瑟夫问题是一个横跨数学与计算机科学的经典挑战,蕴含了深刻的逻辑推理与算法思想。其核心在于如何高效解决一个看似简单的淘汰游戏,但其背后的递归特性和数据结构优化方法却极具启发性。这一问题不仅具有理论研究价值,更在操作系统调度、加密算法设计、游戏开发等实际应用中展现出独特的实用性。本文旨在通过多角度剖析约瑟夫问题,探索其基础解法与高级优化,并为读者提供深入理解此问题的全面视角。 2024.12.9-✍43min

禅宗里有一个词叫做“因缘和合”。 所谓因缘,是指事件要发生所必须的条件。因缘和合就是当你聚集了这件事的一切条件,它就会自然而然的发生。“它就会自然而然的发生”,这种朴素而坚定的价值观让我们感到无比安心,安心到可以不用有任何担心焦虑。 1399

约瑟夫环问题:递归思想解决之道,数学与算法的巧妙融合

约瑟夫环问题是一个经典的数学游戏,它描述了n个人围成一圈,从第一个人开始报数,每次数到m的人出局,然后从下一个人重新开始报数,直到最后只剩下一个人。

2501_93886185的博客 354

约瑟夫环的数学推导(9步简洁易懂的推导)

约瑟夫环的数学推导(9步简洁易懂的推导) 证明过程尽量写的简洁、易懂,参考自文章:这或许是你能找到的最详细约瑟夫环数学推导! 约瑟夫环问题是一个数学问题。我们定义一个函数f(n, k)表示:在n个人围成的环中,从1开始数,数到k的人被杀掉,然后接着从1开始数,直到只剩下一个人,幸存者的编号就是f(n, k)。 1、 假设我们把n个人从0开始编号,分别为0, 1, 2, …, n-2, n-1; 2、 那么很明显,我们的函数有一个最基本的值,就是f(1, k) = 0; 3、 第一个被淘汰的数字肯定是编号为(

m0_54137337的博客 3770

约瑟夫斯环问题的几种经典解法

经典的约瑟夫斯 问题描述: 有n个人围成一圈,从1开始顺序排号。从第一个人开始报数(从1~3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号? 数组循环模拟法 const int N = 1000; int person[N]={0}; int getJosePhus(int n,int m) { if (n <= 0 || m <= 0) //检查参数...

dielu7895的博客 1116

约瑟夫问题Josephus problem

约瑟夫问题:经典算法已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。例如:n = 9, k = 1, m = 5 【解答】出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。

其实我不会编程,只会脸滚键盘 2344

简单解决约瑟夫环的方法

约瑟夫问题: 编号为 1-N 的 N 个士兵围坐在一起形成一个圆圈,从编号为 1 的士兵开始依次报数(1,2,3…这样依次报),数到 m 的 士兵会被杀死出列,之后的士兵再从 1 开始报数。直到最后剩下一士兵,求这个士兵的编号。 这道题可以用递归来解决,递归是思路是每次我们删除了某一个士兵之后,我们就对这些士兵重新编号,然后我们的难点就是找出删除前和删除后士兵编号的映射关系。 我们定义递归函数...

D.k的博客 403

左神算法:环形单链表的约瑟夫问题(Java版)

本题来自左神《程序员面试代码指南》“环形单链表的约瑟夫问题”题目。 题目 据说,著名犹太历史学家 Josephus 有过以下故事: 在罗马人占领乔塔帕特后,39 个犹太人与Josephus 及他的朋友躲到一个洞中,39 个犹太人决定宁愿死也不要被敌人抓到,于是决定了一种自杀方式,41 个人排成一个圆圈,由第 1 个人开始报数,报数到 3 的人就自杀,然后再由下一个人重新报 1,报数到 3 的人再自杀,这样依次下去,直到剩下最后一个人时,那个人可以自由选择自己的命运。这就是著名的约瑟夫问题。现在请用单向环.

寒泉 6万+

【约瑟夫环的递归算法的理解】

本文通过约瑟夫环问题(n=9,k=3)阐述了递归算法的推导过程。关键在于发现每次出列后剩余人员会重新编号,形成新的环,从而得出递推公式:f(n)=(f(n-1)+k)%n。该公式表示当前轮幸存者位置与上一轮位置的关系。文中通过具体例子验证了这一规律,并提供了对应的Python实现代码,其中递归基例为n=1时返回0(0-based索引),其他情况则通过递推公式计算。最后通过用户输入测试了算法,输出时需将0-based索引转换为1-based编号。

hnbc2020的博客 226
上一篇: 平面直线切割问题 (LINES IN THE PLANE) 问题
下一篇: 数论前奏-整数和mod
追逐星辰的光
博客等级 码龄10年 12粉丝 221原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值