题目链接:
题意:
一座山上有n个洞,编号为0~n-1。兔子隐藏在某个洞中,狼正在搜寻着兔子,搜寻的第一个洞编号为0。其后狼搜寻着每个m洞,问是否存在安全的洞可供兔子藏身。比如m=2,n=6时,狼不断搜寻编号0,2,4,0的洞,此时1,3,5号洞是安全的。
案例:
Sample Input
2
1 2
2 2
Sample Output
NO
YES
分析:
辗转相除法: 假设求正整数 num1,num2 的最大公约数,假设f(x,y)为两者的最大公约数,取 k = x / y (取整),b = x % y (取余);则 x = k y + b ;那么能同时被x ,y整除的数必然也同时能被 b , y 整除,能被b , y整除的数也能同时被x,y整除,也就是说,x,y的最大公约数就是b,y的最大公约数,则有 f (x , y) = f(y , x%y) (x>=y>0),这样递归运算,比如
f(42,30) = f(30,12) = f(12 , 6) = f(6,0) = 6; 这样将运算次数直接降低了很多。
该题是要求判断出是否能通过约瑟夫环的数数方式将所有的点都数出来,就是判定总人数和跳跃人数是否互质,如果最大公约数是一的话,那么输出NO,否则输出YES。
以下是网络上的证明分析:
设在N个点的圈中,按每数M个标记一下,那么能够把所有的点遍历到即要满足在循环完一圈后,新的起点一定要在1-M中的任何一点出现一次。那么问题就转化为能否遍历1-M中所有的点,依次如此进行下去,当发现不能满足小区间的要求时,那么其父层亦不能满足要求。那么每次起点的偏移量是否有规律呢?答案是有的,以初始的N和M为例,每次的偏移量是 N%M( 假设N> M反之交换位置 ),也即取余的一个过程,那么接下来的新的N就是M,M也就变成了 N%M, 即 N2<-- M1; M2<-- N1% M1;我们设想当N 不为1,而偏移量M又已经为0,那么整个样例也就不可能做到一一查询了。
源代码:
1 #include2 long n,m; 3 int gcd(long a,long b)//查找最大公约数 4 { 5 return b==0?a:gcd(b,a%b); 6 } 7 int main() 8 { 9 int T;10 scanf("%d",&T);11 while(T--)12 {13 scanf("%lld%lld",&n,&m);14 if(gcd(n,m)==1)15 printf("NO\n");16 else17 printf("YES\n");18 }19 return 0;20 }