辗转相除法

作用

求x,y两个数的最大公因数,即$gcd(x,y)$

前置知识

$x,y,a,b,k$都是正整数

把x整除y记为$x|y$

如果$a|x$,$a|y$那么a是x和y的公因数

如果$a|x$,那么$a|kx$ 

如果$a|x$,$a|y$那么$a|x-ky$ (x>ky)

如果$a|b$,$b|a$那么a=b

如果a是x,y的公因数,$b=gcd(x,y)$那么$a|b$

证明(常用证明法)

对于两个整数x,y(x>y)

$gcd(x,y)=gcd(y,x%y)$

$x/y=q...r$可以表示为$x=qy+r$ (x为被除数,y为除数,q为商,r为余数)

那么$gcd(x,y)=gcd(y,r)  $

假设$g1=gcd(x,y)$  $g2=gcd(y,r)$

那么$g1|x$,$g1|y$

由于$g1|y$所以$g1|qy$

那么$g1|x-qy$即$g1|r$

由于$g1|r$、$g1|y$,且$g2=gcd(y,r)$所以$g1|g2$

反过来

因为$g2|y$,$g2|r$

由于$g2|y$所以$g2|qy$

那么$g2|qy+r$即$g2|x$

由于$g2|x$、$g2|y$,且$g1=gcd(y,y)$所以$g2|g1$

由于$g1|g2$、$g2|g1$,所以$g1=g2$

对于$gcd(x,y)$,当x>y时,即可用上述公式进行递归

由于余数r必定小于除数y,所以gcd的两个值x,y一定会越来越小直到$y|x$,所以最终$gcd(x,y)$ (x>y)当y=0时,x即为最大公因数

#include<bits/stdc++.h>
using namespace std;

long long a,b;

long long gcd(long long x,long long y){
    if(x<y) swap(x,y);
    while(y){
        x=x%y;
        if(x<y) swap(x,y);
    }
    return x;
}

int main(){
    scanf("%lld%lld",&a,&b);
    printf("%lld",gcd(a,b));
}
原文地址:https://www.cnblogs.com/lamkip/p/13546911.html