欧几里得算法

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

 

辗转相除法是利用以下性质来确定两个正整数 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);

}

 

 1 //***********************************************************************************************
 2 /*
 3     欧几里得算法也称辗转相除法,如果要求a,b的最大公约数,则gcd(a, b) = gcd(b, a % b),
 4 直到a % b = 0,此时b就是要求的最大公约数。
 5     扩展欧几里得算法是在求最大公约数的基础上求出一组x,y使得x*a + y*b = gcd(a, b)。
 6 这个方程是有多解的,以下算法所求的是满足|x|+|y|最小的一组x0,y0。可以以此x0,y0表示方程
 7 的通解:
 8     x = x0 + (b / a) * t
 9     y = y0 - (a / b) * t 
10     现在我们需要求x,y使之满足a*x + b*y = gcd(a, b)。已知它的下一个状态是b*x1 + a%b*y1 = gcd(a, b)。
11 而a%b可以写成a - (a / b) * b(a/b为指的是整除)。可推得:
12     gcd(b, a % b) = b * x1 + (a - (a / b) * b) * y1
13                   = a * y1 + b * (x1 - (a / b) * y1)
14     gcd(a, b)     = a * x  + b * y
15     所以:
16     x = y1;
17     y = x1 - (a / b) * y1
18     在最终状态时, a = gcd, b = 0。此时就领x = 1, y = 0。(y可以是任何值,等于0时求出来的特解就是
19 |x| + |y|最小的解)。
20 */
21 //************************************************************************************************
22 
23 #include<iostream>
24 #include<cstdio>
25 #include<cstdlib>
26 #include<conio.h>
27 
28 using namespace std;
29 
30 int gcd(int a, int b) {
31     if (b == 0) return a;
32     else return gcd(b, a % b);
33 }
34 
35 int e_gcd(int a, int b, int& x, int& y) {
36     if (b == 0) {
37         x = 1;
38         y = 0;
39         return a;
40     }
41     else {
42         int ans = e_gcd(b, a % b, x, y);
43         int temp = x;
44         x = y;
45         y = temp - (a / b) * y;
46         return ans;
47     }
48 }
49 
50 int main() {
51     int a, b;
52     while (cin >> a >> b) {
53         int x, y;
54         int d1, d2;
55         d1 = gcd(a, b);
56         d2 = e_gcd(a, b, x, y);
57         printf("%d %d %d %d\n", d1, d2, x, y);
58     }
59     _getch();
60     return 0;
61 }

 

 1 //***********************************************************************************************
 2 /*
 3     欧几里得算法也称辗转相除法,如果要求a,b的最大公约数,则gcd(a, b) = gcd(b, a % b),
 4 直到a % b = 0,此时b就是要求的最大公约数。
 5     扩展欧几里得算法是在求最大公约数的基础上求出一组x,y使得x*a + y*b = gcd(a, b)。
 6 这个方程是有多解的,以下算法所求的是满足|x|+|y|最小的一组x0,y0。可以以此x0,y0表示方程
 7 的通解:
 8     x = x0 + (b / a) * t
 9     y = y0 - (a / b) * t 
10     现在我们需要求x,y使之满足a*x + b*y = gcd(a, b)。已知它的下一个状态是b*x1 + a%b*y1 = gcd(a, b)。
11 而a%b可以写成a - (a / b) * b(a/b为指的是整除)。可推得:
12     gcd(b, a % b) = b * x1 + (a - (a / b) * b) * y1
13                   = a * y1 + b * (x1 - (a / b) * y1)
14     gcd(a, b)     = a * x  + b * y
15     所以:
16     x = y1;
17     y = x1 - (a / b) * y1
18     在最终状态时, a = gcd, b = 0。此时就领x = 1, y = 0。(y可以是任何值,等于0时求出来的特解就是
19 |x| + |y|最小的解)。
20 */
21 //************************************************************************************************
22 
23 #include<iostream>
24 #include<cstdio>
25 #include<cstdlib>
26 #include<conio.h>
27 
28 using namespace std;
29 
30 int gcd(int a, int b) {
31     if (b == 0) return a;
32     else return gcd(b, a % b);
33 }
34 
35 int e_gcd(int a, int b, int& x, int& y) {
36     if (b == 0) {
37         x = 1;
38         y = 0;
39         return a;
40     }
41     else {
42         int ans = e_gcd(b, a % b, x, y);
43         int temp = x;
44         x = y;
45         y = temp - (a / b) * y;
46         return ans;
47     }
48 }
49 
50 int main() {
51     int a, b;
52     while (cin >> a >> b) {
53         int x, y;
54         int d1, d2;
55         d1 = gcd(a, b);
56         d2 = e_gcd(a, b, x, y);
57         printf("%d %d %d %d\n", d1, d2, x, y);
58     }
59     _getch();
60     return 0;
61 }

 

posted @ 2016-03-23 22:38  lemadmax  阅读(364)  评论(0编辑  收藏  举报