文章目录
辗转相除
首先要知道:如果
d
d
d能整除
a
a
a,
d
d
d也能整数
b
b
b,即
d
d
d是
a
,
b
a,b
a,b的公因数时,
d
d
d能整除
a
x
+
b
y
ax+by
ax+by,其中
x
x
x和
y
y
y是整数。
这是显然的,令
a
=
k
1
d
a=k_1d
a=k1d,
b
=
k
2
d
b=k_2d
b=k2d,则
(
a
x
+
b
y
)
/
d
=
(
k
1
d
x
+
k
2
d
y
)
/
d
=
k
1
x
+
k
2
y
(ax+by)/d=(k_1dx+k_2dy)/d=k_1x+k_2y
(ax+by)/d=(k1dx+k2dy)/d=k1x+k2y,仍然是整数。
上面的结论可简写成:若
d
∣
a
d|a
d∣a且
d
∣
b
d|b
d∣b , 则
d
∣
(
a
x
+
b
y
)
d|(ax+by)
d∣(ax+by)
而
a
%
b
a\%b
a%b可以写成
a
−
⌊
a
/
b
⌋
∗
b
=
a
−
c
∗
b
a-\lfloor a/b \rfloor * b=a-c*b
a−⌊a/b⌋∗b=a−c∗b,此时
x
=
1
,
y
=
−
c
x=1,y=-c
x=1,y=−c,所以
d
d
d能整除
a
%
b
a\%b
a%b
下面证明 a a a、 b b b的最大公约数 等于 b b b、 a % b a\%b a%b的最大公约数
1、
a
a
a、
b
b
b的所有公约数 都是
b
b
b、
a
%
b
a\%b
a%b的公约数
不妨设
a
a
a和
b
b
b的公约数是
d
d
d
1.1、显然任意
d
d
d都是
b
b
b的约数,即
d
∣
b
d|b
d∣b
1.2、由上面我们知道
d
∣
(
a
%
b
)
d|(a\%b)
d∣(a%b),故任意
d
d
d都是
a
%
b
a\%b
a%b的约数。
所以任意
d
d
d既是
b
b
b的约数也是
a
%
b
a\%b
a%b的约数,是二者的公约数
2、
b
b
b、
a
%
b
a\%b
a%b的所有公约数 都是
a
a
a、
b
b
b的所有公约数
不妨设
b
b
b和
a
%
b
a\%b
a%b的公约数是
d
d
d
2.1、显然任意
d
d
d都是
b
b
b的约数,即
d
∣
b
d|b
d∣b
2.2、
d
∣
a
%
b
d|a\%b
d∣a%b,有
d
∣
(
a
−
c
∗
b
)
d|(a-c*b)
d∣(a−c∗b),又因为
d
∣
b
d|b
d∣b,所以
a
−
c
∗
b
a-c*b
a−c∗b加上
c
∗
b
c*b
c∗b仍然能被
d
d
d整除,即
d
∣
(
a
−
c
∗
b
+
c
∗
b
)
d|(a-c*b+c*b)
d∣(a−c∗b+c∗b),就得到了
d
∣
a
d|a
d∣a
所以任意
d
d
d既是
b
b
b的约数也是
a
a
a的约数,是二者的公约数
#include <iostream>
using namespace std;
int n, a, b;
int gcd(int a, int b) {
// 如果b不是0,则返回b和a%b的最大公约数;如果b是0则返回a
return b ? gcd(b, a % b) : a;
/*if(!b) {
return a;
}
else {
return gcd(b, a % b);
}*/
}
int main() {
scanf("%d", &n);
while(n -- ) {
scanf("%d%d", &a, &b);
printf("%d\n", gcd(a, b));
}
return 0;
}