1欧几里得算法
欧几里得算法(辗转相除法)是解决两个数,a,b的最大共因数的(最大公约数)
中国古代有个 更相减损术(高中课本学过)与此同理
先不管他们那不明觉厉的名字。。。。。看一下思想
假设a,b的最大共因数为gdc
那么 a=k1*gcd,b=k2*gcd
不妨假设a>b(不影响)
则 a=b*t+c
等号两侧同除gcd,因为a/gcd为整数,b*t/gcd为整数
所以c/gcd也为整数
这样a与b的最大共因数也是b与c的最大共因数
即gcd(a,b)==gcd(b,c)=gcd(b,a%b)
int Gcd(int a,int b)
{
if(a<b)
{
int tem=a;
a=b,b=tem;
}
if(!b)
return a;
return Gcd(b,a%b);
}
扩展欧几里得解决的是 ax+by=c 这样的二元一次方程的x,y的解
ax+by=gcd(a,b)一定有(x,y)的整数解,
首先,在欧几里得算法中最后一步会求到gcd(b,a%b)中a%b==0的情况
这样a就是最大共因数
而在上式中 就是 a*1+b*0=gcd(a,0)即x=1,y=0
好啦,先把这放一放
来看一下怎么求解
ax+by=gcd(a,b)=gcd(b,a%b)
=bx0+(a%b)y0
=bx0+(a-a/b*b)y0
=b(x0-a/by0)+ay0
=ay0+b(x0-a/by0)
即x=y0,y=(x0-a/by0)——可以递归求(x,y)了(最终的xn=1,yn=0)
那这样,可以在之前的欧几里得算法的基础上添点东西
把(x,y)求出来了
int exgcd(int a,int b,int &x,int &y){
if(b == 0)
{//已知的特殊情况
x = 1,y = 0;
return a;
}
int d = exgcd(b,a%b,x,y);
int t = x;
x = y,y = t - (a/b)*y;//代入公式
return d;
}