A rabbit must hide in one of the holes. A wolf searches the rabbit in anticlockwise order. The first hole he get into is the one signed with 0. Then he will get into the hole every m holes. For example, m=2 and n=6, the wolf will get into the holes which are signed 0,2,4,0. If the rabbit hides in the hole which signed 1,3 or 5, she will survive. So we call these holes the safe holes.
Input
The input starts with a positive integer P which indicates the number of test cases. Then on the following P lines,each line consists 2 positive integer m and n(0<m,n<2147483648).
Output
For each input m n, if safe holes exist, you should output "YES", else output "NO" in a single line.
Sample Input2 1 2 2 2Sample Output
NO YES
题意理解:
输入m和n两个数,表示一座山底一共环绕有n个洞,狼从第0个洞出发(相当于第1个洞),逆时针找兔子,每次走m个洞。问如果兔子不能被狼找到输出YES,否则输出NO。
解析:
这个问题的关键就在于狼能不能把所有洞遍历一遍,如果能,狼肯定能找到兔子;如果不能,兔子肯定能找个洞躲起来。
设狼当前在第pos个洞,x是狼遍历的次数,pos=m·x%n,该式转换为pos=m·x+n·y(y可正可负),根据欧几里得扩展原理对于不完全为0的非负整数a,b,gcd(a, b)表示a, b的最大公约数,必定存在整数对x,y,满足a·x+b·y=gcd(a, b)。(这里不证明,想深入了解的同学自行百度或csdn)得pos=gcd(a,b)=m·x+n·y。当输入m和n后,必定存在一对x,y满足gcd(a,b)=m·x+n·y,所以x,y可以成倍数增大,在此过程中pos随之改变,所以当gcd(a,b)=1时,pos就可以等于1,2,3,······,n-1这样狼就可以遍历所有的洞了。
代码实现
#include<iostream>
using namespace std;
int gcd(int a,int b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
int a,b;
int n;
cin>>n;
while(n--)
{
cin>>a>>b;
if(gcd(a,b)==1)
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
}
}
return 0;
}
自我备忘录:
说实话我刚看完这道题再联想gcd,想了半天都没个头绪,后来想通过举例子往gcd上靠也找不出规律,没办法参考了多人的解析结合我自己汇总在这篇博客上。