啦啦啦,啦啦啦,我是一位程序员,天天都要敲代码~~~~
欧几里得算法又称辗转相除法,是指用于计算两个非负整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。
------度娘
有朋友可能对gcd(b,a mod b)为啥b在前面,其实这是一个特别巧妙的写法,我们控制前一位永远大于后一位,也就是说后一位一定先到达0,我们这个时候可以减少很多的不必要的判断了
gcd(int a,int b){
if(!b){
return a;
}
return gcd(b,a%b);
}
何为扩展的欧几里得算法
求出ax+by=gcd(a,b)ax+by=gcd(a,b)中对应的x,y出来。
裴蜀定理
对于整数a,b,他们关于x,y的线性不定方程ax+by = d ,ax + by = d,设gcd(a,b) = g ,则可证明g|d,g|d,换句话说,就是g是a,b的最小线性组。
大佬支的招数https://www.cnblogs.com/zhanhonhao/p/11329772.html我们知道,欧几里得算法递归到终点时,b=0,gcd = a,此时x = 1,y= 0;设置了边境,我们反推上去求取 x,y,反推到最后一步的前一步,我们得到x1,y1, 最后一步是不是b*x1 + a%b*y1=gcd ,这个时候我们知道了 gcf , x1,y1,
因为:a%b=a−[a/b]∗b
又因为:b*x1 + a%b*y1=gcd
所以:gcd =b*x1+(a-[a/b])*y1 整理得:gcd=a*y1+(x1-[a/b]*y1)b;
得: x=y1, y=x1-[a/b]*y1
#include <iostream>
#include <cstring>
using namespace std;
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;
}
int main(){
int n;
cin>>n;
while(n--){
int a,b,x,y;
cin>>a>>b;
exgcd(a,b,x,y);
cout<<x<<" "<<y<<endl;
}
}