Codeforces Round #726 (Div. 2) D题解

传送门

题意

\(Alice\)\(Bob\)在玩游戏。
他们从一个正整数\(n\)开始轮流对它进行运算。每个回合,玩家可以从\(n\)中减去一个非\(1\)\(n\)的因数。在他/她的回合中不能移动的玩家输。\(Alice\)总是先动。
注意,他们在每个回合中都要减去当前数字的除数。
你被要求找出如果两名玩家都选择最佳策略,谁将赢得游戏。

思路

证明:

我们先考虑\(n\)为奇数的情况:

  • \(n\)为质数时,先手无法选择任何数。即先手必输
  • \(n\)为合数时,这个奇数的因子必然是奇数,那么这个\(n\)可以被分解为\(p_1*p_2(p_1,p_2均为奇数)\)。那么先手选择\(p_1\),则变为\((p_1-1)*p_2\),后手若选择\(p_2\),那么可以变为\((p_1-2)*p_2\),此时又转移为了两个奇数相乘,即先手必然面对奇数乘奇数的情况,辗转最后可转移成先手面对质数\(*1\)。即先手必输,面对奇数乘偶合数的人必赢。

综上所述若\(n\)为奇数,则先手必输。

在考虑偶数的情况:

  • \(n\)不被\(2\)的幂次整除,即\(n=2^t*k(k为奇数)\)。此时若先手选择\(k\),则后手将面对\((2^t-1)*k\),即面对奇数的情况,由上述所知后手必输。即先手必赢。
  • \(n\)\(2\)的幂次整除,则分为:
    1. \(n=2*t(t为奇数)\),先手只能选择\(2\)的倍数,则后手将面对\(x=(2^k-1)*2^{t-k}\):若\(k\)不为\(1\)\(x=奇数*偶合数\),由上述所知必赢,所以先手必赢;若\(k\)\(1\)\(x=2^{k-1}\),此时同样可以选择\(2^{k-2}\),将\(2^{k-2}\)局面抛给先手,即先手必然面对\(2的奇次幂\),辗转下来必然面对\(2\),先手必输。则综上所述先手必输。
    2. \(n=2*t(t为偶数)\),先手可以选择\(2^{t-1}\),将\(2的奇次幂\)局面抛给后手,则后手必输。即先手必赢。

综上所述若\(n\)不被\(2\)的幂次整除先手必赢,若\(n\)\(2\)的奇次幂先手必输,若\(n\)\(2\)的偶次幂先手必赢。

证毕。

代码

int main() 
{
    int T;
    cin >> T;
    while (T -- ) 
    {
        int n;
        cin >> n;
        
        if (n % 2 != 0) puts("Bob");
        else 
        {
            int cnt = 0;
            while (n % 2 == 0) 
            {
                cnt ++ ;
                n /= 2;
            }
            if (n > 1) puts("Alice");
            else if (cnt % 2 == 0) puts("Alice");
            else puts("Bob");
        }
    }
 
    return 0;
}
posted @ 2021-06-21 03:03  筱翼深凉  阅读(209)  评论(0编辑  收藏  举报