LCM Walk HDU

LCM Walk

Time Limit: 20 Sec

Memory Limit: 256 MB

題目連接

http://acm.hdu.edu.cn/showproblem.php?pid=5584

Description

A frog has just learned some number theory, and can't wait to show his ability to his girlfriend.

Now the frog is sitting on a grid map of infinite rows and columns. Rows are numbered 1,2,⋯ from the bottom, so are the columns. At first the frog is sitting at grid (sx,sy), and begins his journey.

To show his girlfriend his talents in math, he uses a special way of jump. If currently the frog is at the grid (x,y), first of all, he will find the minimum z that can be divided by both x and y, and jump exactly z steps to the up, or to the right. So the next possible grid will be (x+z,y), or (x,y+z).

After a finite number of steps (perhaps zero), he finally finishes at grid (ex,ey). However, he is too tired and he forgets the position of his starting grid!

It will be too stupid to check each grid one by one, so please tell the frog the number of possible starting grids that can reach (ex,ey)!

Input

First line contains an integer T, which indicates the number of test cases.

Every test case contains two integers ex and ey, which is the destination grid.

⋅ 1≤T≤1000.
⋅ 1≤ex,ey≤109.

Output

For every test case, you should output "Case #x: y", where x indicates the case number and counts from 1 and y is the number of possible starting grids.

Sample Input

3
6 10
6 8
2 8

Sample Output

Case #1: 1
Case #2: 2
Case #3: 3

HINT

 

題意

給你(x,y) 然後可以走到(x+lcm(x,y),y)或者走到(x,y+lcm(x,y))

然後現在給你一個位置,問你起點有多少種。

題解:

假設x = pt,y =qt 

所以(pt,qt),那麼下一步就可以走到(pt(1+q),qt)或者走到(pt,(1+p)qt)

那麼很顯然我們走到了(x,y) 那麼上一步就是 (x/(y+1),y)和(x,y/(x+1))

題意:有一隻青蛙,它從起點(x,y)出發,每次它會走LCM(x,y)步[LCM(x,y)就是x,y的最小公倍數]到達點(x+LCM(x,y),y)或點(x,y+LCM(x,y)),最終,它會到達點(ex,ey),現給你終點(ex,ey),要你求出它的起點有多少種可能

解題思路:我們暫時假設x,y的最大公約數gcd(x,y)=k,那麼我們不妨用來表示x,用來表示y,那麼新得到的點必定是,因爲x與y的最小公倍數

我們不妨求解一下新的點x和y的gcd值,以點爲例


因爲時互質的,也是互質的,故

所以,我們可以發現先得到的點和原來的點有相同的最大公約數,故我們可以利用這一點來根據終點求解原先的起點

還有一點需要提及的是,對於當前點(x,y),x,y中小的那個值必定是之前那個點中的x值或y值,故我們可以開始逆推了

#include<iostream>
#include<stdio.h>
using namespace std;

int gcd(int a,int b)
{
    return b==0?a:gcd(b,a%b);
}
int ans = 0;
void solve(int x,int y)
{
    ans++;
    if(x<y)swap(x,y);
    if(x%(y+1)==0)solve(x/(y+1),y);
}
int main()
{
    int t;
    scanf("%d",&t);
    for(int cas=1;cas<=t;cas++)
    {
        ans = 0;
        int x,y;
        scanf("%d%d",&x,&y);
        int p = gcd(x,y);
        x = x/p,y = y/p;
        solve(x,y);
        printf("Case #%d: %d\n",cas,ans);
    }
}


發佈了24 篇原創文章 · 獲贊 28 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章