CF 1537D

题目大意:

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

题目链接:

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

题目思路:

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

  • 若n为奇数:n是质数,必败;否则,n可以表示为 (n = x imes y),其中 x、y是奇数且不等于1或n, 那么减去一个因子就有(x imes y ightarrow (x-1) imes 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
");
        else {
            int cnt=0;
            while(n%2==0) n>>=1,cnt++;
            if(n>1||cnt%2==0) printf("Alice
");
            else printf("Bob
");
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/DeepJay/p/14967629.html