这里是C语言刷题日志,整理了博主本人平时做练习遇到的问题以及相关的总结。不定时对文章内容更新优化,持续维护。
目录
一、题干
牛客网链接
二、题解
1. 辗转相除法
辗转相除法可求出两数的最大公约数,再由公式 最小公倍数 = 两数之积 / 最大公约数 求出最小公倍数。
//辗转相除法求最大公约数、最小公倍数
int main()
{
long long n = 0;
long long m = 0;
//输入两个数
scanf("%lld %lld", &n, &m);
/*因为求最大公约数和最小公倍数都需要用到m、n,且辗转相除的过程会改编n、m的值,
故再创建两个变量n2、m2,把m和n的值拷贝一份再做运算*/
long long m2 = m;
long long n2 = n;
long long r = 0;
//最大公约数
while (r = n2 % m2)
{
n2 = m2;
m2 = r; //注意:m2才是所求的最大公约数的结果,而不是r
}
//最小公倍数 == m*n/最大公约数
printf("%lld", m * n / m2 + m2); //直接求最大公约数和最小公倍数的和
return 0;
}
注意:不需要比较m和n两数的大小再计算。
2. 试除法
设置变量max代表最大公约数,变量min代表最小公倍数。
核心思路为,初始化max与输入的两数中更小的数相等;初始化min与输入两数中更大的数相等。
由最大公约数的规则,max能同时被两数除尽,且为满足条件的数中的最大值。这样一来,只需要让max不断自减,当max自减到恰好可以同时被两数除尽。这时候的max就是最大公约数。
同样,由最小公倍数的规则,min是两数的倍数,即min分别除以两数都能除尽,且为满足条件的最小值。这只需让min不断自增,一个一个向上走,直到恰好满足条件即可。
根据这样的思路,我们能总结出以下的算法:
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n ,&m);
int max = (n>m?m:n);//假设最大公约数,是n和m的较小值
//求最大公约数
while(1)
{
if(n % max == 0 && m % max == 0)
{
break;
}
max--; //max从m与n中的较小值开始不断自减,挨个检查是否满足条件。一旦满足就跳出
}
int min = (n>m?n:m);//假设最小公倍数,是n和m的较大值
//求最小公倍数
while(1)
{
if(min % n == 0 && min % m == 0)
break;
min++; //思路同上,挨个检查
}
printf("%d\n", max+min); //回到题干,题干要求的是求min和max的和
return 0;
}
三、方法总结
1. 辗转相除法最大公约数
虽然上面介绍了用辗转相除法求最小公倍数的操作,但本质上辗转相除法在此是求最大公约数的。因此我们把它拿出来单独强调。
//辗转相除法求最大公约数
int main(){
int m,n;
int tmp = 0;
scanf("%d %d",m,n);
while(tmp = m % n){
m = n;
n = tmp;
}
printf(最大公约数是:"%d",n); //注意,最后的n(也就是模数,右边的那个数)才是要求的最大公约数
}
最小公倍数 == 两数相乘再除以其最大公约数。
2. 迭乘法求最小公倍数
迭乘法的思路是这样的:
由公倍数的定义出发,如果一个数k是a和b的公倍数,那么k可以表示成 a*i 或 b*j 。转换成编程语言表达,即:
//若k为a和b的最小公倍数,则有:
k == a*i
k == b*j
//也就是说,当(a*i) % b == 0时,k是最小公倍数
编写成完整代码,即:
//迭乘法求最小公倍数
int main(){
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); //输入两个数
int i = 1;
while((a*i) % b != 0){
i++;
}
printf("最小公倍数是:%d\n", a * i); //最小公倍数:i*a
return 0;
}
3. 试除法求最大公约数与最小公倍数
和上面提到过的试除法思路相同,就是挨个试。比如要求20和30的最大公约数,那就从20开始挨个往下检查,看看19能不能同时被20和30整除;19不符合条件再往下看18、17、16…直到找到符合条件的。求最小公倍数也一样,就是挨个往上试,总能找到满足条件的,再输出就好了。
确实,试除法的效率相对较低。
//最大公约数
int main()
{
int n = 0;
int m = 0;
scanf("%d %d", &n ,&m);
int max = (n>m?m:n);//假设最大公约数,是n和m的较小值
//求最大公约数
while(1)
{
if(n % max == 0 && m % max == 0)
{
break;
}
max--; //max从m与n中的较小值开始不断自减,挨个检查是否满足条件。一旦满足就跳出
}
printf("最大公约数是 %d",max);
return 0;
}
//最小公倍数
int main(){
int n = 0;
int m = 0;
scanf("%d %d", &n ,&m);
int min = (n>m?n:m);
//求最小公倍数
while(1)
{
if(min % n == 0 && min % m == 0)
break;
min++;
}
printf("最小公倍数是 %d", min);
return 0;
}