题目
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】中
}