今天在牛客网看到这样一题,感觉有点意思。
如题:
小乐乐最近在课上学习了如何求两个正整数的最大公约数与最小公倍数,但是他竟然不会求两个正整数的最大公约数与最小公倍数之和,请你帮助他解决这个问题。
每组输入包含两个正整数n和m。(1 ≤ n ≤ 109,1 ≤ m ≤ 109);
对于每组输入,输出一个正整数,为n和m的最大公约数与最小公倍数之和。
例如:输入:10 20
输出:30
这是用代码的简单实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//定义一个函数,用于辗转相除法求最大公约数
long long big(int a, int b) {
//当满足被除数不为0时循环
while (b > 0) {
//定义一个数用于存储a%b
long long r = a % b;
//将b作为下一个被除数
a = b;
//将所得的余数作为下一个除数
b = r;
}
//返回最大公约数a
return a;
}
int main() {
//定义三个数,用于存储俩整数及最大公约数和最小公倍数之和
long long n, m, sum = 0;
//输入俩整数
scanf("%lld %lld", &n, &m);
//此步可以不要
int i = n * m;
//判断n与m的大小,保证n>m
//若不是,这替换俩数
if (n < m) {
int t = n;
n = m;
m = t;
}
//调用函数big求最大公约数
//其次,有公式n*m=最大公约数*最小公倍数
//所以有(n*m)/最大公约数=最小公倍数
//求其和再相加
sum = big(n, m) + (n * m) / big(n, m);
//输出最大公约数与最小公倍数之和
printf("%lld", sum);
return 0;
}
其中,big函数(辗转相除法)可以用递归算法计算,由于牛客网有内存限制,所以在此给出更好的解法:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//定义一个函数,用于辗转相除法求最大公约数
long long big(int a, int b) {
//递归调用big函数
return (a % b ? big(b, a % b) : a);
}
int main() {
//定义三个数,用于存储俩整数及最大公约数和最小公倍数之和
long long n, m, sum = 0;
//输入俩整数
scanf("%lld %lld", &n, &m);
//此步可以不要
int i = n * m;
//判断n与m的大小,保证n>m
//若不是,这替换俩数
if (n < m) {
int t = n;
n = m;
m = t;
}
//调用函数big求最大公约数
//其次,有公式n*m=最大公约数*最小公倍数
//所以有(n*m)/最大公约数=最小公倍数
//求其和再相加
sum = big(n, m) + (n * m) / big(n, m);
//输出最大公约数与最小公倍数之和
printf("%lld", sum);
return 0;
}
如果喜欢我的博客,麻烦点一下关注和点赞