简介:
辗转相除法,用于求两个整数的最大公因数
辗转相除法[gcd(x,y)];
CSP写法
在CSP-S 2020中,学会写法为:
int gcd(int u,int v){
if(v == 0) return u;
return gcd(v, u % v);
}
课堂讲法
今日上课讲法为:
int m , n , r ;
scanf("%d %d",&m,&n);
for( r = m % n ; r ; ) {
m = n ;
n = r ;
r = m % n ;
}
printf("%d",n);
(校内还未讲函数相关内容)
证明辗转相除法成立:
对于要取公因数的(x),(y),
若(y>x),则必有:(y=kx+r)((k)为(frac{y}{x})的商,(r)为余数)
-
若(r=0),则k为最大公因数,返回值为(frac{y}{x})
-
若(r!=0),则可设最大公因数为(d)。
设(y=ad),(x=bd)
那么可以写为:(ad=kbd+b)⇒(r=ad-kbd=(a-kb)d),则(d)也能整除(r)。所以(d)同时也是(b)与(r)的最大公因数。
- 以此类推,可得:(f=k_1b+r_1);
- (g=k_2r_1+r_2)
- (r_1=k_3r_2+r_3)
- ……
- 直到得到(r_n=k_{n+2}r_{n+1})
得到递归为“CSP写法”。则得到(r_n \% r_{n+1} = 0)时等同于(①)情况,返回值为上一位的(r_{n-1} \% r_n)
完结撒花
奇怪的东西
//据说<algorithm>库里有现成的__gcd(x,y)函数?
stl_algo.h
template<typename _EuclideanRingElement>
_EuclideanRingElement
__gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
{
while (__n != 0)
{
_EuclideanRingElement __t = __m % __n;
__m = __n;
__n = __t;
}
return __m;
}