D.Deleting Divisors(博弈)

题目大意:Alice和Bob玩游戏,Alice先手,每一次他们都要做操作就是将数减去它的因子(他小于自身且不为1的因子)
轮到谁不能做这个操作谁就输了。所以他们会尽力给对方留下质数

链接: https://codeforces.com/problemset/problem/1537/D.

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
#define speed(x) ios::sync_with_stdio(false), cin.tie(x), cout.tie(x)
#define bug(x) cout << #x << " == " << x << '\n'
const ll MAX_N =1e6+10;

int main()
{
    int t;
    scanf("%d" ,&t);
    while(t--)
    {
        ll A;
        scanf("%lld",&A);
        if(A%2==1)
        ///设第一轮的数为A1,如果alice的先手是奇数啊A1的话两种可能
        ///①n为质数,这样子alice一次都拿不了数啦所以Bob赢啦
        ///②因为A1是奇数,所以他的因子也都是奇数A1=B1*B2,alice只能拿奇数B2
        ///所以轮到Bob的时候 该数是偶数,A2=(B1-1)*B2;是一个奇数×偶数的形式
        ///下面证明了谁先手拿到奇数×偶数的偶数谁必胜
        {
            printf("Bob\n");
        }
        else
        {
            int num=0;
            while(A%2==0)
            {
                A/=2;
                num++;
            }
            if(A!=1)
            ///说明A1是一个奇数×偶数的数(即存在奇数因子)
            ///alice每次拿偶数,轮到Bob的时候 该数是奇数
            ///而且不存在Bob拿奇数后,剩下的数为2的情况
            ///e.g:设Bob拿走的奇数为t 2+t=t*k 且k为奇数 ——> 2/t+1==k t只有可能为1,而题目规定拿的数要大于1
            ///所以谁先手拿到奇数×偶数的数谁必胜
            {
                printf("Alice\n");
            }
            else///A1满足2^num=A1
            ///所以alice可以拿2~2^(num-1)之间
            ///①Alice拿2^k(1<=k<num-1)的数,剩下的数为2^n-2^k=2^k*(2^(n-k)-1)为奇数×偶数的偶数这样子Bob必胜了
            ///②Alice拿2^(num-1),同理Bob拿2^(num-2)....相当于每次给这个数/2
            ///可操作次数就是num-1,当num为奇数的时候可操作数为偶数,所以Alice拿到2输掉 反正Bob输掉
            {
                if(num%2==1)
                {
                     printf("Bob\n");
                }
                else
                {
                    printf("Alice\n");
                }
            }
        }
    }
}

上一篇:Splay 板子


下一篇:如何在Google AppEngine数据存储中输入项目?