扩展欧几里得算法 C++ ( 原来还可以这样做 tql )

扩展欧几里得算法

请先熟练理解欧几里得算法定义 以及下面的欧几里得算法代码板子

任何代码,思想最重要!
思想:
先回忆欧几里得算法
辗转相除法求最大公约数
具体的辗转相除法定义,请百度…

//enen 真的简洁 真的妙不可言
int gcd(int a, int b)
{
	return b ? gcd(b, a % b) : a;
}

扩展欧几里得算法思想:

gcd(a,b) 在下面中均 指a,b 的最大公约数

首先 要明白的是 对于任意正整数 a,b 一定存在一对非0 整数 x ,y
使得 ax + by = gcd(a, b)

意思是在欧几里得算法里新添加了两个量 x,y 即每层递归中都存在一对 x,y使得 ax + by = gcd(a, b)成立
这里的a,b对应的是每层递归里的a,b(欧几里得算法)

最终要求 求得最开始的 使得ax + by = gcd(a, b)成立的一对 x,y的值
这问题看起来 很让人蒙蔽 enen是人脑难以解决的问题

其实我们很容易求出递归到最后一层的x,y
也就是 最后一组ax + by = gcd(a, b)的x,y值 很明显 此时x=1,y=0
            why?

          reason:
原因 (欧几里得算法中) 递归到最后时a = 最大公约数 ,b = a%b(此层递归上面的b) 。所以若想此时的公式ax + by = gcd(a,b)成立 ,只有 x = 1,y=0 这时我们就可得知递归到 最后一层的 x,y 了。

如果我们想求出最开始的x,y最好的想法就是找出相邻层的每一对x,y之间的关系 根据递归的回溯 从而求出最开始的 x ,y的值。

问题转化为-----
求相邻层之间的 每一对的 x,y的关系:

这里先看第一层的 x,y的值:
a * x1 + b * y1 = gcd(a,b);

第二层的x,y的值:
b * x2 + a % b * y2 = gcd(a,b);
又因为 a % b = a - (a / b) * b <-----小学知识
所以第二层的x,y的值:
b * x2 + (a - (a / b) * b) * y2 = gcd(a,b);
化简第二层的得:
b * x2 + a * y2 - (a / b ) * b * y2 = gcd(a,b);
b * (x2 - (a / b) * y2) + a * y2 = gcd(a,b);
对应一二层a,b的系数 可求得相邻层之间x,y的关系
y1 = x2 - (a / b) * y2
x1 = y2

因为递归是先知道最后面的 然后一层一层的向上推 知道上一层的值
很显然这里的 x1,y1是上一层 ,x2,y2是下一层。

因此根据相邻层间每对的x,y的关系,就可以一层层的从已知的最后一层,推出最开始的x,y的值。

思想毕,上代码:
普通代码:

int exgcd(int a, int b, int& x, int& y)
{
	if (!b)
	{
		x = 1, y = 0;
		return a;
	}
	int d = exgcd(b, a % b, x, y);
	int temp = y;
	y = x - (a / b) * y;
	x = temp;
	return d;
}

升级版:

int exgcd(int a, int b, int &x, int &y)
{
    if (!b)
    {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

这个 x,y对调位置在回溯的时候省略了 temp 秒啊!!

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镜子的分享

感谢老铁支持!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值