链接:题目
来源:牛客网
题目描述
天才程序员菜哭武和张老师有一天到一个城市旅游,旅途中菜哭武觉得无聊就想和张老师玩一个游戏。菜哭武有n个石子,每个石子都标有1到n之间到数,且各不相同,一开始他们会随机从这堆石子选一个石子放置到一个集合中,张老师选的数是a,菜哭武选的是b(a和b不相同)。接下来菜哭武和张老师轮流按照如下规则拿走一个石子:当石子x能被拿走时,当且仅当集合存在y和z,满足x等于y+z或者y-z,当x被拿走时,把它放到集合中。谁完成最后一轮操作时,谁获胜。张老师总是先手,于是张老师就好奇当决定好a和b时,他是否总是能获胜,你能帮助一下张老师吗?
输入描述:
第一行一个整数T(1≤T≤500),表示共有T组测试数据。
对于每组测试数据,第一行三个整数n(2≤n≤20000)、a和b(1≤a,b≤n, a≠b)。
输出描述:
若张老师能获胜输出Yes,反之No。
示例1
输入
复制16 2 1 2 3 1 3 67 1 2 100 1 2 8 6 8 9 6 8 10 6 8 11 6 8 12 6 8 13 6 8 14 6 8 15 6 8 16 6 8 1314 6 8 1994 1 13 1994 7 12
16 2 1 2 3 1 3 67 1 2 100 1 2 8 6 8 9 6 8 10 6 8 11 6 8 12 6 8 13 6 8 14 6 8 15 6 8 16 6 8 1314 6 8 1994 1 13 1994 7 12
输出
复制No Yes Yes No No No Yes Yes No No Yes Yes No Yes No No
No Yes Yes No No No Yes Yes No No Yes Yes No Yes No No
思路:刚开始拿的石子的数取最大公约数,无论怎么进行y+z还是y-z都是最大公约数的整数倍,求出拿出石子的个数,如果是奇数则输Yes否则输出No
code:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int idex;//记录所拿石子的个数
const int N=2e4+10;
bool vis[N];//标记所拿的石子
int main()
{
int T;
cin>>T;
int n,a,b;
while(T--){
idex=0;
memset(vis,0,sizeof(vis));
cin>>n>>a>>b;
int temp=__gcd(a,b);
vis[a]=vis[b]=1;
for(int i=1;i<=n;i++){
if(!vis[i]&&!(i%temp)){
idex++;
}
}
if(idex&1) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}