zoukankan      html  css  js  c++  java
  • 欧几里得算法

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

    辗转相除法是利用以下性质来确定两个正整数 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
    ", 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
    ", d1, d2, x, y);
    58     }
    59     _getch();
    60     return 0;
    61 }
  • 相关阅读:
    git命令
    Java开发中的23种设计模式详解
    Linux下简单基本操作【备查】
    微信|公众平台开发者平台
    MyEclipse老是弹出problem occurred窗口
    spring 工具包怎么下载
    MyEclipse8.6启动后提示内存不足的解决方案(亲测,完美解决)
    bzoj2440,luoguP4318 完全平方数
    hdu5528
    CF1076E Vasya and a Tree
  • 原文地址:https://www.cnblogs.com/xzrmdx/p/5313484.html
Copyright © 2011-2022 走看看