算法总结之欧几里德算法

算法总结之欧几里德算法

1.欧几里德算法

  欧几里德算法又称辗转相除法,用于计算两个正整数ab的最大公约数。

  其计算原理依赖于下面的定理:

  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为所有解中最接近零的解

原文地址:https://www.cnblogs.com/Enumz/p/3873618.html