2020.10.13辗转相除法
简介:
辗转相除法,用于求两个整数的最大公因数
辗转相除法[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;
}