欧几里得与扩展欧几里得算法

## 欧几里得算法:最大公因数$(gcd)$ 该算法基于: $gcd(a,b)=gcd(b,a$%$b)$

证明:
\(a\) % \(b = r\),

\(a = k * b + r,\)

因此\(r = a - k * b\)

\(d\)\(a,b\)的公约数,那么\(d|a, d|b,\)

\(a - k * b\) 能被\(d\)整除,即\(d|r\),即\(d|(a\) % \(b)\)

因此\(d\)\(b\)\((a\) %\(b)\)的公约数,

因此\(a,b\) 的公约数和\(b, (a\)%\(b)\)的公约数是同一个数,

得出\(gcd(a,b)=gcd(b,a\)%\(b)\)

同时知道\(gcd(a,0)=a\)

因此递归求解即可:

inline int gcd(int a,int b)
{
	if (b==0) return a;
	return gcd(b,a%b);
}

对于这个简单的gcd,背结论不求甚解我觉得是可以dei


扩展欧几里得算法\((exgcd)\)

对于一类形如\(ax+by=gcd(a,b)\)的方程求解其x,y的一组解:

通过辗转法,可得\(bx+y(a\)%\(b)=gcd(b,a\)%\(b)\)

用除法代替取模,则:\(bx+y(a-[a/b]*b)=gcd(b,a\)%\(b)\)(这一步仅仅是原方程的变形)

根据上述欧几里得算法可得,\(gcd(a,b)=gcd(b,a\)%\(b)\)

因此\(ax+by=bx'+y'(a-[a/b]*b)\)

通过乘法分配律和结合律的运算可得:$$ax+by=ay'+b(x'-[a/b]*y')$$

其中,\(x'\)\(y'\)是方程\(bx+y(a-[a/b]*b)=gcd(b,a\%b)\)的解,用来借助这个已经求得的x'和y'结合已知的a和b推得现在的解\(x,y.\)其中\(a\)\(b\)不变。我们可以通过递归来求。

递归的边界:
\(ax+by=gcd(a,0)\)时,即\(b=0\)时,\(x=1\ y=0\).显而易见。

故代码很好理解了吧:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int x,y;
int exgcd(int a,int b)
{
	if (b==0) 
	{ 
	    x=1; 
		y=0; 
		return a; 
	}
	int n=exgcd(b,a%b);
	int t=x;
	x=y; 
	y=t-a/b*y;
	return n;
}
int main(void)
{
	int a,b;
	cin>>a>>b;
	cout<<exgcd(a,b)<<endl;//这里输出最大公约数
	cout<<x<<' '<<y<<endl;//这个输出方程ax+by=gcd(a,b)的解
	return 0;
}

<\font>

posted @ 2018-12-14 15:31  PigZhou  阅读(147)  评论(0编辑  收藏  举报