您的位置:首页 > 其它

欧几里得算法

2016-03-23 22:38 260 查看

欧几里得算法又称辗转相除法,用于计算两个正整数的最大公约数。

辗转相除法是利用以下性质来确定两个正整数 a 和 b 的最大公因子的:

⒈ 若 r 是 a ÷ b 的余数,且r不为0, 则

gcd(a,b) = gcd(b,r)

⒉ a 和其倍数之最大公因子为 a。

另一种写法是:

⒈ 令r为a/b所得余数(0≤r

若 r= 0,算法结束;b 即为答案。

⒉ 互换:置 a←b,b←r,并返回第一步。

实现:

int gcd(int a, int b) {


return b ? gcd(b, a % b) : a;


}

int gcd(int a, int b) {


if(b == 0) return a;

else return gcd(b, a % b);


}

//***********************************************************************************************
/*
欧几里得算法也称辗转相除法,如果要求a,b的最大公约数,则gcd(a, b) = gcd(b, a % b),
直到a % b = 0,此时b就是要求的最大公约数。
扩展欧几里得算法是在求最大公约数的基础上求出一组x,y使得x*a + y*b = gcd(a, b)。
这个方程是有多解的,以下算法所求的是满足|x|+|y|最小的一组x0,y0。可以以此x0,y0表示方程
的通解:
x = x0 + (b / a) * t
y = y0 - (a / b) * t
现在我们需要求x,y使之满足a*x + b*y = gcd(a, b)。已知它的下一个状态是b*x1 + a%b*y1 = gcd(a, b)。
而a%b可以写成a - (a / b) * b(a/b为指的是整除)。可推得:
gcd(b, a % b) = b * x1 + (a - (a / b) * b) * y1
= a * y1 + b * (x1 - (a / b) * y1)
gcd(a, b)     = a * x  + b * y
所以:
x = y1;
y = x1 - (a / b) * y1
在最终状态时, a = gcd, b = 0。此时就领x = 1, y = 0。(y可以是任何值,等于0时求出来的特解就是
|x| + |y|最小的解)。
*/
//************************************************************************************************

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<conio.h>

using namespace std;

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

int e_gcd(int a, int b, int& x, int& y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
else {
int ans = e_gcd(b, a % b, x, y);
int temp = x;
x = y;
y = temp - (a / b) * y;
return ans;
}
}

int main() {
int a, b;
while (cin >> a >> b) {
int x, y;
int d1, d2;
d1 = gcd(a, b);
d2 = e_gcd(a, b, x, y);
printf("%d %d %d %d\n", d1, d2, x, y);
}
_getch();
return 0;
}


//***********************************************************************************************
/*
欧几里得算法也称辗转相除法,如果要求a,b的最大公约数,则gcd(a, b) = gcd(b, a % b),
直到a % b = 0,此时b就是要求的最大公约数。
扩展欧几里得算法是在求最大公约数的基础上求出一组x,y使得x*a + y*b = gcd(a, b)。
这个方程是有多解的,以下算法所求的是满足|x|+|y|最小的一组x0,y0。可以以此x0,y0表示方程
的通解:
x = x0 + (b / a) * t
y = y0 - (a / b) * t
现在我们需要求x,y使之满足a*x + b*y = gcd(a, b)。已知它的下一个状态是b*x1 + a%b*y1 = gcd(a, b)。
而a%b可以写成a - (a / b) * b(a/b为指的是整除)。可推得:
gcd(b, a % b) = b * x1 + (a - (a / b) * b) * y1
= a * y1 + b * (x1 - (a / b) * y1)
gcd(a, b)     = a * x  + b * y
所以:
x = y1;
y = x1 - (a / b) * y1
在最终状态时, a = gcd, b = 0。此时就领x = 1, y = 0。(y可以是任何值,等于0时求出来的特解就是
|x| + |y|最小的解)。
*/
//************************************************************************************************

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<conio.h>

using namespace std;

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

int e_gcd(int a, int b, int& x, int& y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
else {
int ans = e_gcd(b, a % b, x, y);
int temp = x;
x = y;
y = temp - (a / b) * y;
return ans;
}
}

int main() {
int a, b;
while (cin >> a >> b) {
int x, y;
int d1, d2;
d1 = gcd(a, b);
d2 = e_gcd(a, b, x, y);
printf("%d %d %d %d\n", d1, d2, x, y);
}
_getch();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: