BC115 小乐乐与欧几里得

描述

小乐乐最近在课上学习了如何求两个正整数的最大公约数与最小公倍数,但是他竟然不会求两个正整数的最大公约数与最小公倍数之和,请你帮助他解决这个问题。

输入描述:

每组输入包含两个正整数n和m。(1 ≤ n ≤ 109,1 ≤ m ≤ 109)

输出描述:

对于每组输入,输出一个正整数,为n和m的最大公约数与最小公倍数之和。

示例1

输入:10 20

输出:30

示例2

输入:15 20

输出:65

我们其实代码可以这样写,但是,会超时(时间复杂度高)

//题中用long long类型,而不用int类型,防止求最小公倍数的时候,数字过大溢出int
#define _CRT_SECURE_NO_WARNINGS
//求两个数最大公约数和最小公倍数的和
#include<stdio.h>
int main()
{
	long long m = 0;
	long long n = 0;
	scanf("%d %d", &m, &n);
    //1.最大公约数max
	long long max = (m > n) ? n : m;
	while (1)
	{
		if ((m % max == 0) && (n % max == 0)) {
			break;
		}
		max--;
	}

	//2.最小公倍数min
	long long  min = (m > n) ? m : n;
	while (1)
	{
		if ((min % m == 0) && (min % n == 0)) {
			break;
		}
		min++;
	}

	//3.求和
	long long sum = max + min;

	//4.打印
	printf("%lld", sum);
	return 0;
}

求最大公约数常用的有两种方法,一是九章算术中的更相减损术:大数减小数直到相等,相等的数即最大公约数,该算法时间复杂度约为O(N);二是欧几里得的辗转相除法:大数除以小数取余数(相当于模运算),直到余数为零时(也即模运算为零时)的除数(也即模数)就是最大公约数,该算法时间复杂度约为O(logN)

求最小公倍数的方法:原始数据的乘积除以最大公约数

本题数据偏大,选择时间效率更高的辗转相除法更好,第一次提交没通过,发现一组测试用例的输出竟然是负数,一猜肯定是溢出了,然后把数据类型声明改为long long型:

#define _CRT_SECURE_NO_WARNINGS
//求两个数最大公约数和最小公倍数的和
#include<stdio.h>
int main()
{
	long long m = 0;
	long long n = 0;
	scanf("%lld %lld", &m, &n);
	long long m2 = m;
	long long n2 = n;
	//1.最大公约数max
	long long max = 0;
	while (max = m2 % n2)
	{
		m2 = n2;
		n2 = max;
	}

	//2.最小公倍数min
	long long min = m * n / n2;

	//3.求和
	long long sum = min + n2;

	//4.打印
	printf("%lld", sum);

	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.阿Q.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值