/********
辗转相除法的原理:
存在自然数a,b(a > b),求a%b,设a/b = k...d(其中k为整数,d为余数);
那么a = b*k + d;
那么我们可以看作求(b*k + d)与 b 的最大公约数;
显然,b的约数一定是b*k的约数,所以我们要找的最大公约数不应该在b和b*k这两个数之间找,故我们要求的最大公约数就是要找到b跟d的最大公约数,
这点通过一个循环实现,每次判断d是否为零,如果为零,那么上一次循环中作为除数的那个数就是我们要找的最大公约数。(如果不懂,可以对照gcd1部分代码理解)
gcd2函数是后来加的,对于一些已经彻底了解gcd原理的人可以直接拿来用,省时省力;但没有真正了解gcd原理的还是建议先去搞懂,毕竟真正学到的才是自己的。*********/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
int gcd1(int a,int b){
if(a == 0 || b ==0) return 0; // 任何一方为零,gcd为零
int r; //r是一个交换时的第三方变量,无其他含义
while(b){
r = b;
b = a%b;
a = r;
}
return a;
}
int gcd2(int a,int b){
if(a == 0 || b ==0) return 0;
while(a ^= b ^= a ^= b %= a); //这是gcd函数的核心代码(ababa),最后返回b;这个代码的具体展开式我写在了下面的注释部分,实现原理不做赘述
/*b = b % a;
a = a^b;
b = a^b;
a = a^b;
while(a){
b = b % a;
a = a^b;
b = a^b;
a = a^b;
}*/
return b;
}
int main(){
int a,b;
while(cin >> a >> b){
// 如果a < b ,交换a和b
if(a < b){
a = a^b;
b = a^b;
a = a^b;
}
cout << gcd1(a,b) << endl;
cout << gcd2(a,b) << endl;
}
return 0;
}