CF 1537D - Deleting Divisors (博弈?)

题目大意:

给定一个正整数n,两个玩家交替操作。每一回合,一个玩家可以减去n的一个不为1或n的因子(因子集合是随着n的变化而变化的)。当某玩家不能进行操作时,则输掉游戏。

题目链接:

https://codeforces.com/contest/1537/problem/D

题目思路:

对正整数n,分情况进行讨论:

  • 若n为奇数:n是质数,必败;否则,n可以表示为 \(n = x \times y\),其中 x、y是奇数且不等于1或n, 那么减去一个因子就有\(x \times y \rightarrow (x-1) \times y\),转移给对方一个包含奇因子的偶数,而对方可以再减一个奇数,使之再次面临奇数的局面,总之,对方永远能够继续操作,直到自己只剩一个质数。综上n为奇数时必败。
  • 若n为偶数:n包含奇因子,必胜;否则,n可以表示为\(n=2^k\), 减去一个因子可以得到\(2^k-2,2^k-4,...,2^k-2^{k-1}=2^{k-1}\),其中 除了\(2^{k-1}\)以外其余均包含奇因子,那么这样就只需考虑k的奇偶了,显然k为奇数时必败(2是必败),偶数时必胜。

AC代码:

#include<bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
typedef pair<double,double> pdd;
const int N=1e6+5;
const int M=3e5+5;
const int mod=1e9+7;
const int inf=1e9;
#define fi first
#define se second
#define ls (i<<1)
#define rs (i<<1|1)
#define mem(a,b) memset(a,b,sizeof(a))
#define eb emplace_back
#define mk make_pair
LL read()
{
    LL x=0,t=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){ if(ch=='-') t=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
    return x*t;
}
int main()
{
    int T=read();
    while(T--)
    {
        int n=read();
        if(n&1) printf("Bob\n");
        else {
            int cnt=0;
            while(n%2==0) n>>=1,cnt++;
            if(n>1||cnt%2==0) printf("Alice\n");
            else printf("Bob\n");
        }
    }
    return 0;
}

posted @ 2021-07-03 21:35  DeepJay  阅读(127)  评论(0编辑  收藏  举报