谜题:谁赢了比赛?

时间:2013-02-20 19:45:38

标签: c algorithm time-complexity puzzle space-complexity

一群孩子组成一个戒指。选择第一个孩子并且他们从该孩子顺时针开始计数,直到达到固定数字(n,在游戏开始时给出)。当计数达到n时,第n个点上的孩子被淘汰。游戏从下一个孩子开始再次继续,并且该过程一直持续到一个孩子仍然存在。你的目标是打印直到最后一个孩子的位置。

  

例如,如果有10个孩子且固定数n为6,则最后一个孩子的位置是3。

是否有更好的编程算法来解决这个问题?

  

P.S。我知道我们可以使用数组或其他数据结构轻松完成此操作。我只想要最好的策略,最好是数学方法。

1 个答案:

答案 0 :(得分:2)

我认为最简单的方法仍然是写一个复发(几乎是维基百科所说的,放弃对Jan Dvorak的投票):

T(1) = 0
T(c) = (T(c-1)+n) mod c

或者,写为C(没有递归):

int non_fatal_josephus(int children, int n) {
    int result = 0;
    for(int i=2; i<=children; i++)
        result = (result + n) % i;

    return result + 1; //to make it one-based
}

复发说明:

T(c)表示“如果我们从c孩子开始,哪个孩子将获胜”。

T(1)= 0因为如果我们只有1个孩子,她已经赢了(第1个孩子,索引0)。

一般情况是我们总是消灭第n个孩子(索引n-1),一旦我们消除了她,我们就开始用(c-1)孩子重新计算,但这一次,而不是从索引0开始,我们从索引n开始。这解释了+ n:T(c-1)假设计数从0开始。我们使用+ n来移动子索引,就像我们从索引n开始一样。