洛谷 P1029 最大公约数和最小公倍数问题总结
一.求最大公约数的三种方法
(1)穷举法
(2)辗转相除法
(3)辗转相减法
1.穷举法
这是最容易想到,而且是最直接的方法。简言之,就是从1开始,到a,b中比较小的那个结束,看能不能同时被a, b整除(如果能即为公约数),这样一个循环下来一定可以找出GCD。
代码块
// 穷举法
public static int gcd_enumeration(int a, int b){
// 先找出a,b中小的那个
int smaller = a;
if (b < a) {
smaller = b;
}
int gcd = 1;
for (int i = 2; i <= smaller; i++) {
// 如果能同时被a和b除尽,则更新GCD
if ((a % i == 0) &;&; (b % i == 0)) {
gcd = i;
}
}
return gcd;
}
2.辗转相除法
(1)来自伟大数学家欧几里得的发现,gcd(a,b)=gcd(a,a mod b),这是辗转相除的基本理论。好了,有了理论基础,下面总结成算法步骤:
算法流程图
代码块–递归部分
// 辗转相除法(递归写法)
public static int gcd_division_recursive(int a, int b){
if (b == 0) {
return a;
}
return gcd_division_recursive(b, a % b);
}
代码块–迭代部分
// 辗转相除法(迭代写法)
public static int gcd_division_iteration(int a, int b){
while(b != 0){// 为什么用b判断呢?因为b就是用来存a%b的,即上面算法步骤里的r的
int t = b;
b = a % b;
a = t;
}
return a;
}
3.辗转相减法
那就举个栗子瞧瞧看吧。
求32,12的最大公约数:
32 - 12 = 20 (20 > 12)
20 - 12 = 8 (8 < 12)
12 - 8 = 4 (4 < 8)
8 - 4 = 4 (4 == 4)
所以最大公约数是4.
代码块–递归部分
// 辗转相减法(递归写法)
public static int gcd_substract_recursive(int a, int b){
if(a == b)
return a;
return a > b ? gcd_substract_recursive(a - b, b) : gcd_substract_recursive(a, b-a);
}
代码块–迭代部分
public static int gcd_substract_iteration(int a, int b){
// 如果a,b不相等,则用大的数减去小的数,直到相等为止
while(a != b){
if(a > b)
a = a - b;
else
b = b - a;
}
return a;
}
二.最大公约数GCD与最小公倍数LCM性质总结:
X,Y的乘积与其最大公约数与最小公倍数乘积相等。
三.针对题目
代码实现
#include<stdio.h>
#include<iostream>
using namespace std;
int x, y;
int gcd(int a, int b) //(1)辗转除求最大公约数
{
return b == 0 ? a : gcd(b, a%b);
}
int main()
{
//freopen("1.txt", "r", stdin);
cin >> x >> y;
int ans = 0;
for (int i = x; i <= y;i+=x)
{
for (int j = i; j <= y; j+=x)
{
int Gcd = gcd(i, j);
int Lcm = i*j / Gcd; //(2)在性质总结出解释了
if (Gcd == x&&Lcm == y) ans += 2;
}
}
cout << ans;
return 0;
}