Time limit:1 Seconds Memory limit:65536K
Description
在一个遥远的地方,有一座不知名的高山,周围有 n 个兔子的窝,分别标记为 0 至 n-1 。小白兔隐藏在其中,大灰狼从 0 号窝开始按着逆时针的方向寻找,每隔 m 个洞查找一次。 例如: n = 6, m = 2, 则大灰狼寻找窝的序号依次为 0,2,4,0,...。如果小白兔藏在1,3,或5号窝中,那么小白兔则会很安全。
Input
输入以一个正整数P开始,表示有P组测试数据,接着有P行,每行有两个正整数 m 和 n (0 < m,n < 2147483648)。
Output
对于输入的每组 m 和 n, 如果有安全的窝存在,输出 "YES" ,否则输出 "NO"。
Sample Input
2
1 2
2 2
Sample Output
NO
YES
Source
根据题目得这个题目就是让我们求(km mod n)=i这个方程对与i从0到n-1是否都有整数解k;如果都有那么小白兔就找不到安全的窝,输出NO,否则的话输出YES;
将方程变形成km+tn=i;
如果m,n互质,那么对于km+tn=i;若i保持不变
那么方程必然可以表示成(k0+un)m+(t0+vm)n=i;
说明大灰狼必须经过u*n次查找才会找到相同的一个洞,所以u取最小为1,那么在这n次查找中查找的窝必然都是不相同的,而i的取值只能从0到n-1这n个数,所以大灰狼找遍了所有的洞,小白兔找不到安全的窝,输出NO;
如果m,n不互质,即存在大于1的最大公约数d=gcd(m,n);
那么将m,n都除以d,变为mm=m/d,nn=n/d;
此时mm,nn互质,由上得
对于k*mm+t*nn=i;i能取到0到nn-1的所有值;
即 k*m/d+t*n/d=i;(i=0…n/d-1); 1)
将1)式两边都乘以d得:
k*m+t*n=i*d;(i=0…n/d-1)
即k*m+t*n=ii;(ii=0,d,2*d,3*d…n-d);
所以大灰狼只检查了0,2*d,3*d..n-d这几个窝,其他的窝是安全的;所以存在安全的窝
输出YES;
#include<iostream.h>
int gcd(int x,int y)
{
if(y==0) return x;
else return gcd(y,x%y);
}
int main()
{
int n,m,p,i;
while(cin>>p)
{
for(i=1;i<=p;i++)
{
cin>>n>>m;
if (n>m)
{
if (gcd(n,m)>1) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else
{
if (gcd(m,n)>1)
cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
}
return 0;
}