问题描述
$n
$ 个编号为 $0\to n-1
$,从 $0
$ 数到 $k-1
$,数到 $k-1
$ 的人淘汰,从淘汰的人之后重新开始,持续该过程,问最后剩下的人的编号。
问题分析
$n
$ 个人时,淘汰的是第 $k-1
$ 个人。
剩下的人的编号为 $0\to k-2
$ 和 $k\to n-1
$。
重新开始的编号为:
$$ \begin{aligned}
k &\to 0\\
k+1 &\to 1\\
&\vdots\\
k-2 &\to n-2
\end{aligned} $$
假设原问题表示为 $q(n,k)
$,则淘汰一个人并重新编号之后相当于 $q(n-1,k)
$,如果得到 $q(n-1,k)
$ 的答案,然后将编号重新转换回去就可以得到 $q(n,k)
$ 的答案。
从上面的转换中可以看出:
$$ q(n,k)=[q(n-1,k)+k]\bmod n $$
1
2
3
4
5
|
def josephus(n: int, k: int) -> int:
t = 0
for i in range(2, n + 1):
t = (t + k) % i
return t
|
1
2
3
4
5
|
int josephus(int n, int k) {
int t = 0;
for (int i = 1; i <= n; t = (t + k) % i, ++i);
return t;
}
|
例题
参考