约瑟夫环问题(递归解决)

本文详细探讨了约瑟夫环问题的两种情况:求最后一个人的编号和求所有人的死亡顺序。通过递归方法分析思路,并提供代码示例进行说明,解释了如何在数到K的人被枪毙的规则下,找到最后幸存者的编号以及所有人的死亡顺序。文章还阐述了递归过程中编号映射和处理已淘汰人员的关键点。
摘要由CSDN通过智能技术生成


题目1,求最后一个人的编号

N个人围城一圈, 第一个人编号为0, 从0开始,数到K的人枪毙,问最终留下来的人的编号

思路分析

本题用递归的方法, 设f[n][k]含义为总共n个人,数到第k个人枪毙,最终留下的人的编号.
首先执行第一步,从0开始数,枪毙的一定是编号为k-1的人,那么对于接下来n-1个人如何处理?
调用f[n-1][k],返回的是共n-1人时,最终留下的人的编号(注意这个编号从0开始),但是f[n-1][k]是从0开始的,所以需要处理一下映射的问题, (f[n-1][k] + k ) %n,就是相当于将圈旋转了一下,将0映射成了K,这里为什么+k,而不是+k-1,因为f[n-1][k]返回的是一个编号而不是第几个人,这里加上的偏移量应该是人头数,不应该是编号数。
递归出口是当 n == 1应该返回0,编号为0的人

当初思考的时候的一些疑问:对于那些已经被枪毙的人再次编号的时候是如何跳过的?
这个问题需要直接看结果,对于一个递归结果,他返回的就是n个人,每次击杀第k个人的最终人的编号,借助你从n-1层拿来的结果,上一层的结果已经为你考虑好了枪毙的是第几个人,这时你只需要退回去,加上一个人,从n-1个人变成n个人,并且死的是第k个人,将 k ~ n-1 ~0 ~ k-2连成环,算出这个新环里死的是第几个人就行了
代码如下(示例):

    int f(int n ,
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值