HDOJ 2028求n个数的最小公倍数

题目:求n个数的最小公倍数。
对于这个简单的关于数论的题目时,首先需要学会的是求两个数的最大公约数
求最大公约数的方法有辗转相除法,更像减损术
辗转相除法(循环)得到两个数,将小数除大数,如果得到的余数不为0,则将
除数付给被除数,余数赋给除数,再相除求余,判断余数是否为0。

int a, b;
	while(scanf("%d %d", &a, &b) != EOF) {
		int max_ = max(a, b);
		int min_ = min(a, b);
		int mo = max_ % min_;
		while(mo != 0) {
			max_ = min_;
			min_ = mo;
			mo = max_ % min_;
		}
		printf("%d\n", min_);
	}

递归:

int Max_Divisor(int max_, int min_) {
	int mo = max_ % min_;
	if(mo == 0) {
		return min_;
	}
	max_ = min_;
	min_ = mo;
	return Max_Divisor(max_, min_);
}
int a, b;
	while(scanf("%d %d", &a, &b) != EOF) {
		int max_ = max(a, b);
		int min_ = min(a, b);
		printf("%d\n", Max_Divisor(max_, min_));
	}
  1. 更相减损术
    得到两个数,如果两个数同时为偶数,将这两个数都除以2,直到有一个数不为偶数,记录下一共除了几次2,然后用这两个数,大数减小数,如果得到的差和减数相等,就停止,输出用差乘上乘上2 ……次数,如果不等,将差和减数比较,大的减小的,再判断。
int a, b;
	while(scanf("%d %d", &a, &b) != EOF) {
		int max_ = max(a, b);
		int min_ = min(a, b);
		int c;
		int Count = 1;
		while(1) {
			if(min_ % 2 == 0 && max_ % 2 == 0) {
				min_ /= 2;
				max_ /= 2;
				Count *= 2; 
				cout << Count << endl;
				continue;
			}
			c = max_ - min_;
			max_ = max(c, min_);
			min_ = min(c, min_);
			//cout << max_ << min_ << endl;
			if(c == min_) {
				break;
			}
		}
		printf("%d\n", c * Count);

求n个数的最大公倍数,两个数的最小公倍数 = 乘积 / 最大公约数
有(a1, a2, a3,…an), 先求(a1,a2)的最小公倍数,设为ai,再求(ai, a3)的最小公倍数,以此类推,需要n - 1次循环
然后有一个错误的思考:既然公倍数可以这样求,那公约数也可以,然后就求n个数的最大公约数,然后再得到n个数的乘积,再将他们相除,答案是错误的。
所以应该一个一个的求。

//#define LOCAL
#include <iostream>
#include <algorithm>
#include <cstdio>
using std::cout; using std::cin; using std::endl; using std::max; using std::min;
int Get(unsigned int a, unsigned int b) {
	unsigned int mul = a * b;
	unsigned int max_ = max(a, b);
	unsigned int min_ = min(a, b);
    unsigned int mo = max_ % min_;
	while(mo != 0) {
		max_ = min_;
		min_ = mo;
		mo = max_ % min_;
	} 
	return mul / min_;
}
int main() {
	int n;
	while(scanf("%d", &n) != EOF) {
		unsigned int m[10000];
		for(int i = 0; i < n; i++) {
			scanf("%u", &m[i]);
		}
		for(int i = 0; i < n; i++) {
			if(i + 1 == n) break;
			m[i + 1] = Get(m[i], m[i + 1]);
		}
		printf("%u\n", m[n - 1]);
	}
} 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Greatljc

你的鼓励是我最大的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值