CF1537D Deleting Divisors

Alice 和 Bob 轮流对正整数 \(n\) 进行操作。每次操作减去当前\(n\) 的一个因子 \(d,d\neq 1,d\neq n\)。不能操作判负。

如果 \(n\) 是质数,显然先手必败。如果 \(n\) 不是质数,我们分三种情况讨论:

  1. \(n\) 为奇数;
  2. \(n\) 为偶数但不是 \(2\) 的幂;
  3. \(n\)\(2\) 的幂。

如果 \(n\) 为奇数,则 \(n\) 的所有因子都是奇数,所以减去任意的因子 \(d\),得到的 \(n-d\) 都是偶数。而且因为 \(n\) 还有其它的奇数因子(已经保证了 \(n\) 不是质数),所以 \(n-d\) 也不是 \(2\) 的幂。转移到了情况 2。

如果 \(n\) 为偶数但不是 \(2\) 的幂,我们不妨减去一个奇数因子 \(d\),转移到情况 1。如果 \(n-d\) 是质数,则先手必胜;如果 \(n-d\) 不是质数,则一定会在下一步转移回到情况 2。我们可以通过这样的操作,使得己方永远保持在情况 2,也就永远不会输(情况 2 不会走到质数)。游戏可以在有限步内结束,则对方一定会输。所以,情况 2 先手必胜,情况 1 先手必败。

对于情况 3,我们有两种操作方式:

  • 减去一个 2;
  • 减去 \(\dfrac{n}{2}\)

如果减去 \(2\),就转移到情况 2,对方先手必胜,不可取,只能减去 \(\dfrac{n}{2}\)。此时双方轮流将 \(n\) 折半,\(\log_2 n\) 为奇数时先手必败,为偶数时先手必胜。

void solve() {
    int n;
    cin >> n;
    if (n & 1) {
        cout << "Bob\n";
        return;
    }
    int cnt = 0;
    while (n % 2 == 0)  n /= 2, cnt++;
    if (n != 1) cout << "Alice\n";
    else cout << ((cnt & 1) ? "Bob" : "Alice") << '\n';
}
posted @ 2025-03-21 13:44  XYukari  阅读(14)  评论(0)    收藏  举报