CodeForces-1152C Neko does Maths(GCD)

题目传送门:CodeForces-1152C Neko does Maths

题目大意:

给你两个值a,b,让你求出使lcm(a+k,b+k),最小的k值

gcd性质:

gcd性质:gcd(a,a) = gcd(a,a)
     gcd(a,b) = gcd(a,a-b)(a>b)
 
     gcd(a,b) = gcd(b,a-b)(a>b)
证明:设gcd(a,b)=z; a=zx ,b=zy ,a-b=z(x-y)
    要证明a-b和b的gcd等于a和b的gcd
    b=zy a-b=z(x-y) 则需要证明y和x-y互质即可,这样他们gcd同为z

    x和y显然为质数,存在两种情况
x和y其中不存在2:设x=2m-1 y=2n-1,则x-y=2(m-n)为一个偶数,显然x-y和质数y互质
    x和y其中存在2:设x=2m+1 y=2 ,则x-y=2m-1 显然x-y和2互质。
    成立。

 分析:

lcm(a+k,b+k) = (a+k)*(b+k) / gcd(a+k,b+k). 要使得lcm(a+k,b+k)最小,则需要gcd(a+k,b+k)最大

设gcd(a+k,b+k) = z. 则存在 (a+k)%z = (b+k)%z = 0;     a%z = b%z (a - b) % z = 0
所以 a+k 和 b+k 的最大公约数z,是(a-b)的约数
因为gcd(a+k,b+k)=gcd(a+k,a-b)

因此可以枚举(a-b)的因子,将a+k凑至存在该因子,则k =(x-a%x)(x为因子),进行判断lcm即可。

代码:

#include<iostream>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}
ll lcm(ll a,ll b){
    return a*b/gcd(a,b);
}
ll a,b,mmax,ans=0;
void solve(int x)
{
    int temp=x-a%x;            //将a凑至存在因子x 
    if(lcm(a+temp,b+temp)<mmax){
        ans=temp;
        mmax=lcm(temp+a,b+temp);
    }
}
int main(){
    cin>>a>>b;
    if(a<b)swap(a,b);

    int c=a-b;
    mmax=lcm(a,b);
    for(int i=1;i*i<=c;i++){    //枚举a-b的因子 
        if(c%i==0){
            solve(i);
            solve(c/i);
        }
    }
    cout<<ans<<endl;
    return 0;
}

 参考:https://www.cnblogs.com/dancewithautomation/archive/2012/06/23/2559451.html

原文地址:https://www.cnblogs.com/LjwCarrot/p/10778130.html