hdu5584 lcm&gcd

来源:互联网 发布:济南网络服务公司 编辑:程序博客网 时间:2024/06/08 14:32

有一个蛤, 会gcd。设当前点为(x,y) 每次可以行走(x+lcm(x,y),y)或者
(x,lcm(x,y)+y) 或者不走,给你当前点。问你他是从那些点过来的。
一开始是递推,你知道的一看是dp我就头大。。后来发现了我去
原来每次移动的点gcd(x,y)都是不变的。
设上一次为(x,y-b)
x*(y-b)/gcd(x,y-b)=b;
x*y==b*(gcd(x,y-b)+x)
发现如果知道了上一个的gcd就可以了求出b了。然后往后推出来。
可以证明gcd是不变的。

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#include <math.h>using namespace std;typedef long long LL;LL gcd(LL a,LL b){     return b?gcd(b,a%b):a;}LL lcm(LL a,LL b){    return a/gcd(a,b)*b;}int main(){    int t;    LL a,b,g;    scanf("%d",&t);    for(int cas=1;cas<=t;cas++)    {        scanf("%lld%lld",&a,&b);        LL ans=1;        g=gcd(a,b);       while(1)       {           if(a>b)swap(a,b);           LL aa=a+g;           LL cc=a*b;           if(cc%aa!=0)break;           else           {               LL k=cc/aa;               if(lcm(a,b-k)!=k)break;               ans++;b-=k;           }          // cout<<a<<" "<<b<<endl;       }        printf("Case #%d: %lld\n",cas,ans);    }    return 0;}
原创粉丝点击