约瑟夫环问题

约瑟夫环算法

####一个经典的游戏问题:在一片大海上,由于船上的资源不足,不得以必须将一部分人丢掉海里,才能让剩下的人活下来,船长提议大家首位相接凑成一个圆环,船上共有50人,从船长依次从0到1,2,3开始查数,被查到7的人就要被丢到海里,然后被丢到海里的人的下一个人继续从1开始查数,往复操作,直到船上剩下25人为止,那么请问被丢下到海里的人都是哪些人?

首先,我们不妨将这个问题缩小化,看看是否能找出一般的规律,然后进行归纳

我们将这个问题缩小 假设有7个人,每次第4个人被扔到海里,直到剩下最后一个人
最初的人 0 1 2 3 4 5 6
第一次后 0 1 2 4 5 6
第二次后 1 2 4 5 6
第三次后 1 2 4 6
。。。
通过以上的规律我们 可以知道以下
(1)第一次被扔下海的一定是3(也就是4号)
(2)第二次被扔的0(也就是1号),这个0是我们怎么算出来的呢,是(3+4)%7=0
(3)第三次被扔下的是5,(0+4)%6,但是这次我们把已经被丢掉海里的3号重新计算了一次,这就产生了一个不连续的问题,但是怎么办呢,我们不妨将这些不连续的数字设计成一个环,如下所示

标记 0 1 2 3 4 5 6
最初的人 0 1 2 3 4 5 6

标记 3 4 5 0 1 2
第一次后 0 1 2 4 5 6

标记 0 1 2 3 4
第二次后 1 2 4 5 6

这样设计后,我们会发现这些标记每次都是连续的,这样我们每次只对标记做加减,就避免了因删掉数字而有空缺位置的问题了,但是怎么得到实际的被扔到海里的数字呢,仔细观察,我们会发现规律 以第二次为例 新的数字=(旧的数字-4)%6

归纳出以下:

public int dg(int sum,int value,int n){
if(n==1){
return (sum+value-1)%sum;
}else{
return (dg(sum-1,value,n-1)+value)%sum;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值