【 OJ 】 HDOJ1019 18年10月31日17:05 [ 18 ]

本文深入探讨了最小公倍数和最大公因数的计算方法,包括辗转相除法、相减法及直接求最小公倍数的技巧。提供了详细的算法实现代码,并通过实例解释了每种方法的工作原理。

开始对头这题我第一反应竟然是用...暴搜一个个上去找最小公倍数....显然有点LOW

网上看了人家的求解方法思路基本集中:a*b/GCD(a,b)

所以这题又变成了求最大公因数,网上基本思路3个,

(1) 一个个暴搜

(2) 辗转相除法:

有两整数a和b:

① a%b得余数c

② 若c=0,则b即为两数的最大公约数

③ 若c≠0,则a=b,b=c,再回去执行①

 int gcd(int a,int b)
 {
    return b==0?a:gcd(b,a%b);
 }

形象点的:

int GCD(int a, int b) {
	//return b == 0 ? a : GCD(b, a%b);
	int temp;
	while (b) {
		temp = a%b;
		a = b;
		b = temp;
	}
	return a;
}

(3)相减法


有两整数a和b:

① 若a>b,则a=a-b

② 若a<b,则b=b-a

③ 若a=b,则a(或b)即为两数的最大公约数

④ 若a≠b,则再回去执行①

例如求27和15的最大公约数过程为:

27-15=12( 15>12 ) 15-12=3( 12>3 )

12-3=9( 9>3 ) 9-3=6( 6>3 )

6-3=3( 3==3 )

因此,3即为最大公约数

看别人代码的时候发现一个思路感觉蛮好的,偷过来,这个是直接求最小公倍数,

如果一个数字是同时是a和b的共同倍数,那么每次只要将最大的数字每次加自己本身即可(每次都加a自己本身那么一定是a的倍数)....那么直至找到是b的倍数的时候就是二者最小公倍数.....思路简单直接明了.....
 

int GCD(int a,int b){
    temp_a=a;
    while(!(a%b)){
        a+=temp_a;
    }
    return a;
}//正常人的正常正向思维 = =~tu血
//或者可以写成
int GCD(int a,int b){
  static int first_a=a;
  return !(a%b)?a:GCD(a+first_a,b);
}//只能用一次....重复使用 static 显然不行的....此处只是强写成递归

------------------------------------------------------------------------

下面是我的AC代码

# include<iostream>
using namespace std;
int num[200];//初设200
int GCD(int a, int b) {
	//return b == 0 ? a : GCD(b, a%b); 这个简化有点意思
	int temp;
	while (b) {
		temp = a%b;
		a = b;
		b = temp;
	}
	return a;
}
int LCM(int a, int b) {
	return a / GCD(a, b)*b;//一般a*b/GCD  但是a*b 有可能会超过范围
}
int main(void) {
	int n, index;
	int n2;
	int sum = 1;
	cin >> n;
	while (n--) {
		cin >> n2;
		sum = 1;
		for (index = 0;index<n2; index++) {
			cin >> num[index];
			sum = LCM(sum, num[index ]);
		}
		cout << sum << endl;
	}
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值