约瑟夫环问题——递归解决

问题:

约瑟夫,是一个古犹太人,曾经在一次罗马叛乱中担任将军,后来战败,他和朋友及另外39个人躲在一口井里,但还是被发现了。罗马人表示只要投降就不死,约瑟夫想投降,可是其他人坚决不同意。怎么办呢,他想到一个主意:
让41个人围成一个圆圈,从第一个人开始报数,数到3的那个人被旁边的人杀死。这样就可以避免自杀了,因为犹太人的信仰是禁止自杀的。结果一群人杀来杀去最后只剩下两个了,就是约瑟夫和他朋友,于是两人愉快地去投降了。

请问:约瑟夫和朋友站在什么位置才保住了性命?(即原始位置应该在哪?)

【举例】
(1)假设5个人,数到3杀一个
0 1 2 3 4
A B C1 D E ——初始位置,C第一个被杀
D E A2 B——重新排位,A第二个被杀
B D E3——E第三个被杀
B4 D——B第四个被杀
D——D活了下来,初始位置为3
(2)假设4个人
0 1 2 3
A B C1 D
D A B2
D2 A
A

对于5个人:下一次new跟上一次old报数时,同一个人的下标规律为:old = (new+3)%5

即:old = (new+m)%n ——n为人数,m为间隔数
令:f(n,m)=old 则f(n-1,m)=new
有:f(n,m) = (f(n-1,m)+m)%n

故而可用递归解决

//输入数:0~n-1  输出:最后一个被杀的人的原始下标
//n:人数  m:报数记录
//每次报数从0开始,下角标为old=(new+3)%n
import java.util.Scanner;
public class Main
{
   
    public static void main(String[] args
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值