算法总结之欧几里德算法
1.欧几里德算法
欧几里德算法又称辗转相除法,用于计算两个正整数a,b的最大公约数。
其计算原理依赖于下面的定理:
gcd(a,b) = gcd(b,a mod b) (a>b 且a mod b 不为0)
代码实现:
1 int gcd(int a,int b) 2 { 3 return b==0?a:gcd(b,a%b); 4 }
2.扩展欧几里德算法
基本算法:
对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y,使得 gcd(a,b)=ax+by。
证明:
则我们先来假设方程的ax+by=gcd(a,b)=d的一个正整数解为x1,y1;别怀疑,这个方程一定有解
则有ax1+by1=gcd(a,b) (1)
又对于方程bx +(a%b)y =gcd(b,a%b)有解x2,y2(假设)
则有bx2+(a%b)y2=gcd (b,a%b) = gcd(a, b) (2)
又a%b = a - (a/b)*b;
则(2)式变为bx2+(a-(a/b)*b)y2=gcd(a,b);
即 ay2 + b(x2-(a/b)*y2) = gcd (a,b) (3) ;
对比(1)(3)得
x1=y2;y1=x2-(a/b)*y2
故,ax+by=gcd(a,b)的解只需要在方程bx+(a%b)y=gcd(b,a%b)的解的基础上进行简单的运算就变成原来方程的解,
因为gcd不断递推时会有b=0的情况出现,故可以通过递推来得到方程的解。
代码实现:
1 LL extended_gcd(LL a,LL b,LL &x,LL &y) //返回值为gcd(a,b) 2 { 3 LL ret,tmp; 4 if (b==0) 5 { 6 x=1,y=0; 7 return a; 8 } 9 ret=extended_gcd(b,a%b,x,y); 10 tmp=x; 11 x=y; 12 y=tmp-a/b*y; 13 return ret; 14 }
3.一些结论
1) 方程 Ax+By=C 满足条件:C=K*Gcd(A,B) (K为整数) 则方程存在整数解。反之无解。
2) 设a,b,c为任意整数。若方程ax+by=c的一组整数解为(x0,y0),则它的任意整数解都可以写成(x0+kb‘,y0-ka‘),其中a‘=a/gcd(a,b),b‘=b/gcd(a,b),k为任意整数。
3) 若求出一组整数解(x1,x2) 设x0=x1%b‘ y0=y1%b‘ 则x0,y0为所有解中最接近零的解。
原文:http://www.cnblogs.com/Enumz/p/3873618.html