1 条题解

  • 0
    @ 2025-6-16 14:18:40

    题意分析

    这是一个基于约瑟夫问题的变种题目。题目描述了一个经典的约瑟夫环淘汰游戏:nn个人围成一圈,从2号开始每隔1人淘汰1人(即淘汰2,4,6,...),直到只剩1人。Mike记得自己的编号mm和被淘汰前剩余人数kk,要求找出满足条件的可能的最小nn

    解题思路

    解题关键在于逆向推导约瑟夫问题的过程。对于给定的mmkk,我们需要找到最小的nn使得在淘汰过程中,当剩余kk人时Mike尚未被淘汰。代码中的joseph函数采用递归方式处理:

    1. m=1m=1时直接返回2k12k-1
    2. mm为偶数时计算一个线性关系
    3. mm为奇数时分两种情况递归求解

    该解法利用了约瑟夫问题的数学性质,通过递归将问题规模不断缩小,最终合并子问题的解。对于每个测试用例,算法要么返回满足条件的最小nn,要么返回"Impossible"表示无解。时间复杂度主要取决于递归深度,由于每次递归问题规模减半,可以保证较高的效率。

    #include<iostream>
    using namespace std;
    typedef long long LL;
    LL joseph(LL m, LL k) {
        if (m == 1) return 2 * k - 1;
        else if (m % 2 == 0) {
            LL n = m / 2 - 1 + k;
            if (n >= m) return n;
            else return 0;
        }
        else {
            LL n1 = joseph((m + 1) / 2, k) * 2;
            LL n2 = joseph((m - 1) / 2, k) * 2 + 1;
            if (n2 == 1) n2 = 0;
            if (n1 > 0 && n2 > 0)
                return min(n1, n2);
            else
                return max(n1, n2);
        }
    }
    
    int main() {
        LL m, k;
        while (cin >> m >> k) {
            if (m == 0 && k == 0) break;
            LL ans = joseph(m, k);
            if (ans > 0)
                cout << ans << endl;
            else
                cout << "Impossible" << endl;
        }
        return 0;
    }
    
    • 1

    信息

    ID
    2924
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者