输入两个正整数m和n,求其最大公约数和最小公倍数。
两个整数
最大公约数,最小公倍数
5 7
1 35
#include
int gcd(int a,int b)
{
for(int i=a;i>=1;i--)
{
if(a%i!=0||b%i!=0)
continue;
else
return i;
}
}
int lcm(int a,int b)
{
int i,j;
i=gcd(a,b);
j=a*b/i;
return j;
}
int main()
{
int a,b,i,j;
scanf("%d%d",&a,&b);
i=gcd(a,b);
j=lcm(a,b);
printf("%d %d",i,j);
return 0;
}
思路:将输入的两个数其中一个,进行循环递减,找到他们的共同的因数即为最大公因数。最小公倍数=a*b/最大公因数。
直接法思路简单,但输入数据较大时,时间复杂度高,这里不推荐测试数据量大的数据。
#include
int main()
{
int m, n;
int j, k;
int lcm, gcd = 1;
scanf("%d %d", &m, &n); //输入m和n
j = m, k = n; //用j和k表示m和n,不破坏m与n的值
if (j > k)
{
j = n, k = m; //确保j是较小的那个
}
for (int i = 2; i <= j; i++) //循环寻找从i到j的因子(注意j是可变的,而i会被重置)
{
if (j % i == 0 && k % i == 0) //判断i是否为j和k的公因子
{
j /= i;
k /= i; //j与k分别除以i
gcd *= i; //gcd乘以i
i = 1; //将i重置为1 (循环末尾会i++)
}
}
lcm = gcd * j * k; //求出最小公倍数lcm
printf("%d %d", gcd, lcm); //输出gcd与lcm
return 0;
}
假设我们输入 m=12,n=18 ,初始化最大公约数 gcd=1
我们发现 2 是12和18的一个公因子
我们令 m /= 2 ,n /= 2 ,gcd *= 2
现在 m == 6 , n == 9 , gcd == 2
又发现 3 是 6 和 9 的一个公因子
我们令 m /= 3 , n /= 3 , gcd *= 3
现在m == 2 , n == 3 , gcd == 6
我们找不到除 1 以外的 2 和 3 的公因子了
所以现在的 gcd == 6 就是我们要找的最大公因数
而最小公倍数 lcm = gcd * m * n = 6 * 2 * 3 = 36
短除法可能便于理解,但效率其实并不理想,时间复杂度可以达到O(n)(当输入质数时)
#include
int gcd(int a, int b)
{
return (a % b == 0) ? b : gcd(b, a % b);
}
int main()
{
int m, n;
scanf("%d %d", &m, &n);
int ans = gcd(m, n);
printf("%d %d\n", ans, m * n / ans);
return 0;
}
思路:
辗转相除法是一种用于计算两个整数最大公约数的算法,核心是运用了 gcd( a, b ) = gcd( b, a mod b ) 这一公式(其中 b != 0 )
视频观看