约瑟夫环问题

对于我这是一个老大难问题,很开心今天把它解决了。

解法来源:
https://www.cnblogs.com/daimingming/p/3242406.html

假设有m个人,喊到k出队,假设这样的情况下最后出队的人的编号是Joseph(m, k)。
在这里插入图片描述
看图中的情况,要求Joseph(10, 3),假设把2拿走,然后剩下的数从3开始计算,这样一步一步下去得到最终的答案。如果我们给它们重新编上号,也就是3 4 5 6 7 8 9 0 1 编号为0 1 2 3 4 5 6 7 8,这就是Joseph(9, 3)的问题,如果我们可以求得它的值,再找到这个值在3 4 5 6 7 8 9 0 1序列中对应的值,就可以得到Joseph(10, 3)的值(可以看上面的图来对应)。
对应的公式是:
Joseph(m, k) = (Joseph(m-1, k) + k) % m
加k的原因是这应该从k开始。
迭代的终止情况是m==1,此时直接返回0就行了。
代码是:

int Joseph(int m, int k) {
	if (m == 1)
		return 0;
	else
		return (Joseph(m-1, k) + k) % m;

思路应该是三步:假设求Joseph(10, 3)
1.把拿掉2之后的0 1 3 4 5 6 7 8 9转换为3 4 5 6 7 8 9 0 1,也就是从3开始
2.把3 4 5 6 7 8 9 0 1重新编号0 1 2 3 4 5 6 7 8,意识到这是m=9,k=3的问题,也就是Joseph(9,3)
3.把Joseph(9, 3)的值(代表的是0 1 2 3 4 5 6 7 8里面的值),要将它转换到对应的3 4 5 6 7 8 9 0 1里面的值,找到规律,写出(Joseph(m-1, k) + k) % m这个公式。

确实不太好记忆,可能需要再多看几遍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值