最大公约数与最小公倍数
原问题:计蒜客T1400
问题描述:

样例输入:
3 6 6 12 11 33 22
样例输出:
6 1 11
题意:
就是求最大公约数。(于是拓展学习一下,把最大公约数和最小公倍数都搞定)
最大公倍数:
方法一:辗转相除法(欧几里得算法)--两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。(以小数除大数,如果能整除,那么小数就是所求的最大公约数。否则就用余数来除刚才的除数;再用这新除法的余数去除刚才的余数。依此类推,直到一个除法能够整除,这时作为除数的数就是所求的最大公约数)
【当两个数都较大时,采用辗转相除法比较方便】
//辗转相除递归版 #include<bits/stdc++.h> using namespace std; int MaxY(int a, int b) { int Max, Min; Max=a>b?a:b; Min=a<b?a:b; if(Max%Min==0) return Min; else return MaxY(Min, Max%Min); } int main() { int a, b; cin>>a>>b; cout<<MaxY(a,b)<<endl; return 0; }
//辗转相除非递归版 #include<bits/stdc++.h> using namespace std; int MaxY(int a, int b) { int Max, Min, r; Max=a>b?a:b; Min=a<b?a:b; if(Max%Min==0) return Min; while(Max%Min!=0) { r=Max%Min; Max=Min; Min=r; } return Min; } int main() { int a, b; cin>>a>>b; cout<<MaxY(a,b)<<endl; return 0; }
方法二:辗转相减法(尼考曼彻斯法)--大数减小数,直到两数相等时,相等时的数即为最大公约数。
//辗转相减法 #include<bits/stdc++.h> using namespace std; int gcd(int a, int b) { while(a!=b) { if(a>b) a-=b; else b-=a; } return a; } int main() { int a, b; cin>>a>>b; cout<<gcd(a,b)<<endl; return 0; }
方法三:穷举法
//穷举法 #include<bits/stdc++.h> using namespace std; int gcd(int a, int b) { int temp=0, Min; Min=a<b?a:b; //从两数中较小的那个开始向下枚举即可 for(temp=Min; ;temp--) { if(a%temp==0&&b%temp==0) break; } return temp; } int main() { int a, b; cin>>a>>b; cout<<gcd(a,b)<<endl; return 0; }
最小公倍数:
方法一:穷举法,从两者中最大的数开始,向上加,直到可以使对两数同时取余都为零。(一种不知道该怎么评价的方法...)
方法二:两个整数的最小公倍数,等于两整数之积除以最大公约数--lcm=a*b/gcd(a,b)( 有时候两数乘积会超过整数的范围,可以调整一下乘除顺序--lcm=a/gcd(a,b)*b)
AC代码:(此题)
#include<bits/stdc++.h> using namespace std; typedef long long ll; int gcd(ll a, ll b) { ll Max, Min; Max=a>b?a:b; Min=a<b?a:b; if(Max%Min==0) return Min; else return gcd(Min, Max%Min); } int main() { int n; ll a, b; cin>>n; while(n--) { cin>>a>>b; cout<<gcd(a,b)<<endl; } return 0; }
【注:此题数据比较大,穷举会TLE】

浙公网安备 33010602011771号