描述
题解
一只疯狂的青蛙位于 (x,y) ,每次只能朝 (x+lcm(x,y),y) 或 (x,y+lcm(x,y)) ,但是青蛙初始的位置并不是题目给出的,题目只给出 (ex,ey) ,也就是青蛙最后跳到的地方,问青蛙有多少种 (x,y) 的可能,也就是起点的存在。
一开始很容易想成,青蛙每次可以朝两个位置跳,那么所有跳到 (ex,ey) 的路径一定是一个二叉树形状的,而答案一定是这些路径上的点数,但是事实并非如此。
正着分析,假设
gcd(x,y)=k
,那么我们设
x=ak,y=bk
,那么下一次跳到的点必然是
(ak+abk,bk)
或者
(ak,bk+abk)
。我们拿前者来考虑,
(ak+abk,bk)=((1+b)ak,bk)
,
a
和
如此这般,我们从终点往前推也就成了单一路径的查找了。
接着上述并非如此来说,青蛙正着从一个起点往后跳,的确是一个二叉树的路径,可是这并不意味着一个点可以由两个点跳过来。这个题准确说有些像根据二叉树的父子节点关系进行从叶到根的一个路径查询操作。
代码
#include <iostream>
using namespace std;
int gcd(int x, int y)
{
return y ? gcd(y, x % y) : x;
}
int x, y;
int main()
{
int T;
scanf("%d", &T);
for (int t = 1; t <= T; t++)
{
scanf("%d%d", &x, &y);
if (x > y)
{
swap(x, y);
}
int cnt = 1;
int k = gcd(x, y);
while (y % (x + k) == 0)
{
cnt++;
y = y / (x / k + 1);
if (x > y)
{
swap(x, y);
}
k = gcd(x, y);
}
printf("Case #%d: %d\n", t, cnt);
}
return 0;
}