随笔 - 145  文章 - 0  评论 - 6  阅读 - 18万

扩展欧几里得算法模板

对于整数a,b,x,y,c

有a*x+b*y=c,如果c不是a与b的最大公约数的倍数,那么此方程无解

证明:设gcd(a,b)=d,即最大公约数,那么a*x%d=0,b*y%d=0

则(a*x+b*y)%d=0,说明c是一个d的倍数,相反的,如果c不是d的倍数,那么次方程无解

对于欧几里得算法 int extend_eulid(int a,int b,int &x,int &y)

返回值是a,b的最大公约数,求解的x和y满足a*x+b*y=d的一个解

那么如何求a*x+b*y=c的解呢?假设x0,y0,是通过欧几里得算出来的一个解,即a*x0+b*y0=d,因为c%d=0

因此:a*x0*(c/d)+b*y0*(c/d)=d*(c/d)转化为  a*(x0*(c/d))+b*(y0*(c/d))=c

所以算出a*x+b*y=c的解  x=x0*(c/d), y=y0*(c/d)。

令r=fabs(b/d);//保证为正数

minx = (x%r+r)%r为最小非负解(这一点没想明白)

 

因为gcd(a,b)=gcd(b,a%b)=d

a*x+b*y=d,b*x0+(a%b)y0=d

所以a*x+b*y=b*x0+(a%b)y0

    =b*x0+(a-a/b*b)y0

    =a*y0+b*(x0-a/b*y0)

因此x=y0, y = x0 – a / b * y0;

由此可得到递归程序:

复制代码
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 int extend_euclid(int a,int b,int &x,int &y)
 7 {
 8     //b等于0时递归结束,得到该步的解,通过该解返回到上一步的出上一步的解
 9     if(b==0)
10     {
11         x=1;
12         y=0;
13         return a;
14     }
15     int d = extend_euclid(b,a%b,x,y);
16     int t = x;
17     x=y;
18     y=t-a/b*y;
19     return d;//a,b的最大公约数
20 }
21 int main()
22 {
23     int x,y;
24     printf("%d\n",extend_euclid(9,15,x,y));
25     printf("%d% d\n",x,y);
26     return 0;
27 }
复制代码

 

posted on   wastonl  阅读(264)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示