最大公约数
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;
}