计算机上级复试资料

为什么辗转相除法可以求最大公约数

2019-04-26  本文已影响0人  zju_dream

假设有a,b两个数(a>b),求它们的最大公约数。

  1. a = b*k + c
  2. c = a - b*k
  3. 设d为a和b的公约数(b是从公约数中任取出来的)
  4. 所以d也是b和c的公约数(举例:a为3*5,b为2*5, d为5,c为1*5, a-b(c)的结果肯定是d的n倍,所以d也是b和c的公约数)
  5. 所以d既是a和b的公约数,也是b和c(a%b)的公约数
  6. 由d的任意性可得:a和b的公约数都是b和a%b的公约数。
  7. a = b*k + c,同理可得b和a%b的公约数都是a和b的公约数。(相当于是以小推大)
  8. 综上所述:a和b的公约数与b和a%b的公约数全部相等,故其最大公约数也相等,gcd(a, b) = gcd(b, a%b)

c++实现
注意点

  • 如果a>b,交换两者的位置
  • 递归边界:0和任意整数a的公约数都是a(注意:不是0)
  1. 递归式:gcd(a, b) = gcd(b, a%b)
  2. 递归边界:gcd(a, 0) = a
#include <iostream>
#include <algorithm>
using namespace std;

/*
you can write in a simplier way.

int gcd(int a, int b) {
    return b == 0? b: gcd(a, a%b);
}
*/

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

int main(int argc, char const *argv[])
{
    int a, b;
    while(scanf("%d%d", &a, &b) != EOF) {
        if(a < b) swap(a, b);
        int res = gcd(a, b);
        printf("%d\n", res);
    }
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读