Joseph Problem

【分析】

举个具体的例子

[ 0 1 2 3 4 5 ] n = 6 k = 3 ,解为 f ( 6 , k )

第一轮开始
[ 0 1 × 3 4 5 ] ,编号为 2 的玩家被踢出

f [ 3 4 5 0 1 ] ,重新排列以保持模 6 意义下的连续性,此时的下标系统记为 f n = 5 k = 3 ,解为 f ( 5 , k ) ,并有 f ( 6 , k ) = f ( 5 , k ) 成立

f [ 0 1 2 3 4 ] ,重新从 0 开始编号,又回到了 f 下标系统

观察从下标系统 f 到下标系统 f 的变换关系, f f :首先加 k = 3 ,然后模 n = 6

从而有 f ( 6 , k ) = f ( 5 , k ) = ( f ( 5 , k ) + k ) % 6

同理可得
f ( 5 , k ) = ( f ( 4 , k ) + k ) % 5
f ( 4 , k ) = ( f ( 3 , k ) + k ) % 4
f ( 3 , k ) = ( f ( 2 , k ) + k ) % 3
f ( 2 , k ) = ( f ( 1 , k ) + k ) % 2
直到边界 n = 1 f ( 1 , k ) = 0

于是可得递推公式
f ( n , k ) = { 0 n = 1 ( f ( n 1 , k ) + k ) % n n > 1

【练习】
nowcoder 圆圈中最后剩下的数

【代码】

int JosephProblem( int n, int k )
{ 
    int result = 0;

    for( int i = 2; i <= n; i++ )
        result = ( result + k ) % i;

    return result;
}

猜你喜欢

转载自blog.csdn.net/o0Helloworld0o/article/details/81414151