约瑟夫环
问题描述
个人围成一圈报数,报到 的人被淘汰,接着他的下一个人又开始重新报数。如此反复,直至只剩下一个人,求最后的胜利者。
问题分析
记胜利者编号为 ,则:
1.当 时,圈子中只有一名小伙伴,该小伙伴即为获胜者,即: 。
2.当 时,我们可以通过观察 淘汰一人之后变化,从而寻找与 的联系。
如下图所示,淘汰掉 号之后, 号小伙伴重新开始报数。
观察右图:
求得: ,由此我们不难发现 淘汰一人之后,与
相对应。
代码如下
int findTheWinner(int n, int m) {
if(n == 1) return 1;
return (findTheWinner(n - 1, m) + m - 1) % n + 1;
}