约瑟夫环问题

问题描述请参考 🐻度娘 .

在这里设一共有 \(n\) 个人,标号分别为 \(0,...,n-1\),剔除序号为 \(m\) ,报数从 1 开始。

一种显而易见的解法是使用链表模拟:

int main()
{
    int n = 5, m = 3;
    list<int> people;
    for (int i = 0; i < n; i++)
        people.push_back(i);
    int num = 0;
    auto itor = people.begin();
    while (people.size() > 1)
    {
        auto cur = itor;
        num++;
        if ((++itor) == people.end())
            itor = people.begin();
        if (num == m)
        {
            num = 0;
            people.erase(cur);
        }
    }
    cout << people.front() << endl;
}

这样做的算法复杂度是 \(O(m*n)\) , 空间复杂度是 \(O(n)\)

下面考虑数学解法。

(老实说,看了几个证明,都没看懂😅)

先放结论:\(p_i = (p_{i-1} + m) \mod i, 2 \le i \le n\) .

初始条件:\(p_1 = 0\) .

代码:

int math(int n, int m)
{
    int p = 0;
    for (int i = 2; i <= n; i++)  p = (p + m) % i;
    return p;
}
posted @ 2020-06-28 15:26  sinkinben  阅读(159)  评论(0编辑  收藏  举报