最大公约数

c++

最大公约数

/*
    定理:
        求解正整数 x, y 的最大公约数 gcd(x, y),等价于求解 gcd(y, x mod y)
    证明:
        使用分类讨论的方法证明:
        当 x > y:
            gcd(x, y) = gcd(y, x % y) 证明:
            t = x % y = x - int(x / y) * y
            对于 x, y, t 而言,我们讨论:
            对于 x, y 均存在的约数,那么一定也是 t 的约数。
                也就是说 t 和 y 的公约数,包含 x 的公约数。
            对于 x 不存在,y存在的约数,t 一定不存在,因为 x = t + int(x / y) * y, 倘若 t 存在该约数,那么 x 一定存在,和假设不符。
                也就是说 x 和 y 不存在的公约数,y t 一定不存在。
                假设 存在约数 m 是 (y, t) 的公约数,但不是 (x, y) 的公约数,也就是说 m 是 y、t 的约数,但不是 x 的约数,和上面条件不符。
            因此,(x, y) 的公约数集合 等于 (y, t) 公约数的集合。 gcd(x, y) = gcd(y, t)
        当 x = y:
            gcd(x, y) == gcd(y, 0)
            而因为 0 和 x 的最大公约数为 x,因此 gcd(y, 0) = y
        当 x < y:
            gcd(x, y) = gcd(y, x % y) = gcd(y, x) 返回到情形 1 中。

        最后因为 gcd(x, y) -> gcd(y, x % y) 是递减的,一定可以到 gcd(x, 0) 的递归终点。
 */
#include <cstdio>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <unordered_map>

using namespace std;

int n;
int gcd(int x, int y) {
    if (y == 0) {
        return x;
    } else {
        return gcd(y, x % y);
    }
}

int main()
{
    scanf("%d", &n);

    int x, y;
    while(n -- ) {
        scanf("%d%d", &x, &y);
        printf("%d\n", gcd(x, y));
    }


    return 0;
}

posted @ 2022-06-27 13:05  lucky_light  阅读(152)  评论(0编辑  收藏  举报