Date:2022.02.04
题意:a、b游戏,每次抽出n的一个约数,其中这个约数不等于1或n自身,之后n变成n-抽出的约数。a是先手,直到n中无法抽出任何一个约数,当前抽的那个人输。问最后谁赢。

思路:枚举一个数的所有约数,若任意一个约数是偶数(注意,每一步约数不能算1和自身),则表示n能分为偶数次拿出,每次拿出是n/此偶数,因此a获胜。若不存在,b获胜。之后喜提wa2,打表之后显然遗漏了一种特殊情况。例如:8满足条件,但以每一次拿4为例 ------ a先拿出4、b拿出2,还剩下2该a拿,a不就寄了吗?打表发现这些数都是2?2^?2?,其中???为奇数,因此特判即可。其实2的奇数次幂一定是b赢好理解,就以8、32为例模拟一下,每次不论a先怎么分、分多少,每次取最大n/2…取最小2,取多少b都会让a寄。此外这题卡LL。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--)
{
vector<int>v;int n;cin>>n;int x=n,cnt=0;bool flag=false;
if(n==2) {cout<<"Bob"<<endl;continue;}
while(x%2==0) {x/=2;cnt++;}
if(x==1&&cnt%2==1) {cout<<"Bob"<<endl;continue;}//2的奇数次幂
x=n;
for(int i=1;i<=x/i;i++)
if(x%i==0&&i!=1&&i!=x)
{
v.push_back(i);
if(i%2==0) {flag=true;break;}
if(i!=x/i)
{
v.push_back(x/i);
if(i%2==0) {flag=true;break;}
}
}
if(flag) cout<<"Alice"<<endl;
else cout<<"Bob"<<endl;
}
return 0;
}
本文解析了关于游戏a、b的胜负规则,关键在于判断n能否被偶数次约分。偶数次约分意味着Alice赢,而2的奇数次幂则判定为Bob胜利。通过代码实现和特判2的奇数次幂,解决了比赛中的特殊情形。
300

被折叠的 条评论
为什么被折叠?



