题目描述
有n个位置按顺时钟排列成一个圆,分别编号从1∼n。一只青蛙最开始在1号位置上,它每次可以跳往与之相隔k个位置的位置上。比如,n=5,k=2时, 青蛙从位置1可以按逆时钟方向跳到位置3,也可以按顺时钟方向跳到位置4。请问这只青蛙能跳到所有的位置上吗?
输入
第一行输入一个整数 T(1≤T≤1000),表示样例的个数。 以后每行一个样例,为两个整数n(1≤n≤109),k(0≤k≤n−2)。
输出
每行输出一个样例的结果。如果青蛙可以到达所有位置,输出"Yes",否则输出"No".
样例输入
2 5 2 4 1样例输出
Yes No样例解释
第一个样例,青蛙一直按顺时钟跳,依次的位置为 1,4,2,5,3; 第二个样例,青蛙只能跳到1,3两个位置。
解题思路: 题目这个 k 给的就很迷惑,他说的是 相隔k个,不想太麻烦,就直接把他转换成 青蛙每次可以跳 k+1 个位置。
其实道理很简单, n 个 数 组成的一个圈, 看青蛙跳完第一圈的时候,会不会回到初始位置1。如果回到1,那么说明之后每次跳的位置都和第一圈一样,那么他永远到不了所有的位置( 当k != 0 时,k=0是可以的)。 那如果 到 第二圈时,青蛙初始位置非1,根据数值偏差,之后的圈,总能跳到之前未到达过的位置,如此,青蛙即能抵达所有位置。
转换成数学问题就是:
找 n 和 k+1 有没有公因数,如果公因数非1,说明n能整除k+1,那么在每一圈,青蛙都会跳出一个完整的⚪,然后回到起始点位置1。(可以画图模拟一下)。而如果不能整除,青蛙就不会跳出一个完整的⚪,所以到下一圈就可以跳到不是1的位置,以此往复,就可以跳满整个圆。
AC代码:
#include <stdio.h>
int gcd(int x,int y){
return y>0 ? gcd (y,x%y) : x;
}
int main()
{
int T,n,k;
scanf("%d",&T);
while ( T --)
{
scanf("%d %d",&n,&k);
if (gcd(n,k+1) == 1) puts("Yes");
else puts("No");
}
return 0;
}
文章讨论了一只青蛙在圆周上跳跃的问题,通过将跳跃间隔k+1理解为有效跳跃步数,分析青蛙能否遍历所有位置的关键在于n和k+1是否有公因数。如果存在公因数,青蛙可以形成完整的圆圈并覆盖所有位置;否则,无法覆盖全部。给出的AC代码展示了利用GCD方法来判断能否到达所有位置。

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



