http://acm.hdu.edu.cn/showproblem.php?pid=5584
题意:
现在有坐标(x,y),设它们的最小公倍数为k,接下来可以移动到(x+k,y)或者(x,y+k)。现在给出终点坐标,求有多少个起点可以通过这种变化方式得到终点。
思路:
现在假设我们处于(x,y)这个坐标上,x和y的最大公约数为k,x和y用k来表示的话可以表示为x=$m_{1}$,y=$m_{2}$。
那么接下来可以得到($m_{1}$k,$m_{2}$k+$m_{1}$$m_{2}$k)或者 ($m_{1}$$m_{2}$k,$m_{2}$k)。(这里$m_{1}$$m_{2}$k就是x和y的最小公倍数)
可以看到坐标变化前后它们的最大公约数都是相同的,都是k。然后根据这两个坐标进行逆推即可,每次只需要保留小的那个坐标,这样就能保证gcd还能为k。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 6 int x, y; 7 8 int gcd(int a, int b) 9 { 10 return b==0?a:gcd(b,a%b); 11 } 12 13 int main() 14 { 15 int T; 16 scanf("%d",&T); 17 int kase = 0; 18 while(T--) 19 { 20 scanf("%d%d",&x,&y); 21 int ans = 0; 22 if(x>y) swap(x,y); 23 int k = gcd(x,y); 24 while(y%(x+k)==0) 25 { 26 y=y/(x/k+1); 27 ans++; 28 if(x>y) swap(x,y); 29 } 30 printf("Case #%d: ",++kase); 31 printf("%d ",ans+1); 32 } 33 }