(扩展)欧几里德算法

本文详细解读了欧几里得算法及其扩展应用,通过状态转移的概念,阐述了如何求解最大公约数,并进一步介绍了扩展欧几里得算法,通过实例演示了如何利用该算法求解x和y的值,从而达到更深层次的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新博文地址:  [状态转移思想解读:欧几里德算法及扩展](http://blog.youkuaiyun.com/sunliymonkey/article/details/46755983)



欧几里德是用来求最大公约数的,可以把它看成是状态转移,

对任意两个数a,b(a>b),d=gcd(a,b),如果b不为零,那么gcd(a,b)=gcd(b,a%b)

        证明: 令 r=a%b,即存在k,使得 a=b*k+r,那么r=a-b*k;显然r>=0,  r%d=((a%d)-(b*k)%d)%d,因为a%d=b%d=0,所以r%d=0;

因此求gcd(a,b)可以转移到求gcd(b,a%b),那么这就是个递归过程了,那什么时候递归结束呢,想一下,a,b不能为零,则可以把当b为零,作为递归的结束(当然还可以以其它结束条件),这就是求最大公约数的方法可以以其它结束条件),这就是求最大公约数的方法


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

是不是很简单呀.

理解了上面,那么扩展欧几里得就能很容易理解了,对任意a,b(a>b),我们列出这样一个式子: a*x+b*y=gcd(a,b);

不要觉得扩展欧几里得很牛逼,它就是一个算x,y的一个方法,只是在上面gcd中多了处理x,y的步骤

我们这样来想:

已知当前的一个状态:a1  b1  x1  y1,    a1*x1+b1*y1=gcd(a1,b1),注意这里的a1,b1是求gcd(a,b)中的一个状态,

假设 (a1,b1)是由(a0,b0)转移过去的

那么:   a1=b0 ;     b1=a0%b0=a0-k*b0 (k=int(a0/b0));gcd(a0,b0)=gcd(a1,b1);

代入a1*x1+b1*y1=gcd(a1,b1),变化成:b0*x1+(a0-k*b0)*y1=gcd(a1,b1)=gcd(a0,b0);

a0*y1+b0*(x1-k*y1)=gcd(a0,b0);

这样可以得到: x0=y1;  y0=x1-k*y1;(理解这个过程了么,由当前状态可以算出上一状态的x,y,即当前状态可以由它的下一个状态的x,y得到)

code:

int exGcd(int a,int b,int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;// 此时a是最开始(a,b)的最大公约数,那么  gcd(a,b)*1+ 0*0=gcd(a,b),肯定对的,在这里,我认为,y可以为任何值都对
	}
	
	int d=exGcd(b,a%b,y,x);
	y-=a/b*x;
	return d;//返回最大公约数
}

应用:

扩展欧几里得算法的应用基本全都是基于:a*x+b*y=d 这个式子来发散的






评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值