约瑟夫环问题

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

解法来源:
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这个公式。

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

posted @ 2019-09-17 21:57  于老师的父亲王老爷子  阅读(18)  评论(0编辑  收藏  举报