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");
}
}
}
}
}
标签:偶数,博弈,奇数,Alice,alice,A1,Bob,Deleting,Divisors 来源: https://blog.csdn.net/qq_51379351/article/details/118709061