杭电OJ_2028 Lowest Common Multiple Plus

题目

Lowest Common Multiple Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 97514 Accepted Submission(s): 40459

Problem Description
求n个数的最小公倍数。

Input
输入包含多个测试实例,每个测试实例的开始是一个正整数n,然后是n个正整数。

Output
为每组测试数据输出它们的最小公倍数,每个测试实例的输出占一行。你可以假设最后的输出是一个32位的整数。

Sample Input
2 4 6
3 2 5 7

Sample Output
12
70

解题思路

//首先, 两个数的最小公倍数 = (两个数相乘) / 最大公约数
//若为三个数,则求出两个数的最小公倍数,再用该最小公倍数和第三个数求 最小公倍数
//多个数,以此类推…
//附:求两个数的最大公因数有:1、辗转相除法;2、辗转相减法;3、穷举法
//我认为效率1>2>3,但是我嚼得某些范围的时候也不一定(具体我不不纠结啦)

哔哔赖赖

我花了几个小时终于整好了这题,最后觉得要Accepted了,但是!!!就是不给我过!!!Wrong Answer!!!我********* “ 哔————————”
然后查阅了一下资料,看到别人说数据会溢出,可以把先乘后除改成先除后乘。我一改,还真AC了!!!原来,数据好容易溢出的说,我要试试把数据类型改成长整型试试!!!

划重点!!!吃完午饭试了一下,就是数据溢出的问题!!!我把int型数据改成long int 的,采用先乘后除的方式(也就是数据可能比较大的方式),还是Wrong Answer。然后我再改成long long int 型, Accepted了!!!帅啊,这后台测试数据里面肯定有特别大大大的数据,还真就是实践出真知~~

改动前:(求两数的最小公倍数时采用先乘后除,此时数据用long long int型才能AC)

//找len个数的最小公倍数 
int b_search_lowest(int *&arr,int len) {
	for (int i = 1; i < len; i++) {
		int fac = arr[0] * arr[i];
		int highest = b_search_two_highest(arr[0],arr[i]);
		arr[0] = fac / highest;		//两个数的最小公倍数 = (两个数相乘) / 最大公约数
	}
	return arr[0];	//以上for循环思路就是把每次求得的最小公倍数存在arr【0】中 
}

改动后:(求两数最小公倍数时采用先除后乘,此时用 int 型就够了,能AC)

//找len个数的最小公倍数 
int b_search_lowest(int *&arr,int len) {
	for (int i = 1; i < len; i++) {
		int highest = b_search_two_highest(arr[0],arr[i]);
		arr[0] = arr[0] * (arr[i] / highest);		//两个数的最小公倍数 = (两个数相乘) / 最大公约数
	}
	return arr[0];	//以上for循环思路就是把每次求得的最小公倍数存在arr【0】中 
}

AC代码

//首先, 两个数的最小公倍数 = (两个数相乘) / 最大公约数
//若为三个数,则求出两个数的最小公倍数,再用该最小公倍数和第三个数求 最小公倍数
//多个数,以此类推...  
//附:求两个数的最大公因数有:1、辗转相除法;2、辗转相减法;3、穷举法
//我认为效率1>2>3,但是我嚼得某些范围的时候也不一定(具体我不不纠结啦)
#include <iostream> 

using namespace std;

void b_init(int *&arr,int len);
void b_delete(int *&arr); 
int b_search_two_highest(int a,int b);
int b_search_lowest(int *&arr,int len); 

int main() {
	int *arr; //定义指向整型数组的指针 
	int n;
	while (scanf("%d", &n) != EOF) {
		b_init(arr,n);	//初始化(动态内存分配、输入数据)
		
		b_search_lowest(arr,n);
		
		cout << arr[0] << endl;
		
		b_delete(arr);	//记得释放这组内存 
	} 
	return 0; 
}

//初始化(动态内存分配、输入数据)
void b_init(int *&arr,int len) {
	arr = new int [len];
	for (int i = 0; i < len; i++) {
		cin >> arr[i];
	}
}
//释放动态分配的内存
void b_delete(int *&arr) {
	delete []arr;
} 
//找两个数的最大公因数
int b_search_two_highest(int a,int b) {
	//采用辗转相除法 
	int t;
	while (a % b != 0) {
		t = a % b;
		a = b;
		b = t;
	} 
	return b;
}
//找len个数的最小公倍数 
int b_search_lowest(int *&arr,int len) {
	for (int i = 1; i < len; i++) {
		int highest = b_search_two_highest(arr[0],arr[i]);
		arr[0] = arr[0] * (arr[i] / highest);		//两个数的最小公倍数 = (两个数相乘) / 最大公约数
	}
	return arr[0];	//以上for循环思路就是把每次求得的最小公倍数存在arr【0】中 
}
发布了24 篇原创文章 · 获赞 0 · 访问量 712

猜你喜欢

转载自blog.csdn.net/qq_44296342/article/details/104182184
今日推荐