hdu 5584 LCM Walk
分析:
-
终点为 ( e x , e y ) (ex,ey) (ex,ey) , 令上一步为 ( x , y ) (x,y) (x,y)
由倒数第二步到最后一步分为两种情况: ( x , y + z ) , ( x + z , y ) , z = l c m ( x , y ) (x,y+z),(x+z,y) ,z=lcm(x,y) (x,y+z),(x+z,y),z=lcm(x,y)
又因为: z > = m a x ( x , y ) z>=max(x,y) z>=max(x,y) , 故可以根据 e x ex ex 和 e y ey ey 的大小确定是哪一种情况
-
关键一步: g c d ( e x , e y ) = = g c d ( x , y ) gcd(ex,ey)==gcd(x,y) gcd(ex,ey)==gcd(x,y) , 因为不管是哪一种情况,加上 z z z , g c d gcd gcd 是不变的
-
故此,设 e x < e y , ( e x , e y ) = ( x , y + z ) ex<ey , (ex,ey)=(x,y+z) ex<ey,(ex,ey)=(x,y+z)
令 g c d = d , e y = x y / d + y → y = e y / ( x / d + 1 ) gcd=d , ey=xy/d+y rightarrow y=ey/(x/d+1) gcd=d,ey=xy/d+y→y=ey/(x/d+1)
重复最后一步到最后一步的逆推过程(再将倒数第二步当最后一步),便可推回起点
-
最后便是考虑逆推的结束条件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <bits/stdc++.h> using namespace std; inline int gcd(int a,int b) { return a%b==0 ?b:gcd(b,a%b); } signed main() { int T,op=0; scanf("%d",&T); while(T--) { int x,y; scanf("%d%d",&x,&y); if(x>y) swap(x,y); int d=gcd(x,y),cnt=1; while(y%(x+d)==0) { cnt++; y=y/(x/d+1); if(x>y) swap(x,y); d=gcd(x,y); } printf("Case #%d: %dn",++op,cnt); } return 0; }
最后
以上就是友好月亮最近收集整理的关于hdu 5584 LCM Walk(gcd,逆推)的全部内容,更多相关hdu内容请搜索靠谱客的其他文章。
发表评论 取消回复