Least Common Multiple
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 56268 Accepted Submission(s): 21413
Problem Description
The least common multiple (LCM) of a set of positive integers is the smallest positive integer which is divisible by all the numbers in the set. For example, the LCM of 5, 7 and 15 is 105.
Input
Input will consist of multiple problem instances. The first line of the input will contain a single integer indicating the number of problem instances. Each instance will consist of a single line of the form m n1 n2 n3 ... nm where m is the number of integers
in the set and n1 ... nm are the integers. All integers will be positive and lie within the range of a 32-bit integer.
Output
For each problem instance, output a single line containing the corresponding LCM. All results will lie in the range of a 32-bit integer.
Sample Input
2 3 5 7 15 6 4 10296 936 1287 792 1
Sample Output
10510296
翻译:求多个数的最小公倍数
核心:明白求质因子的最快方法,可以参看我的博客快速求质因子,这里我也简单讲一下
虽然是java代码,但是和c c++也差不多
private static List<Integer> getPrimeFactor(int num) { List<Integer> primeFactorList = new ArrayList<>(); for (int i = 2; i * i < num; i++) { if (num % i == 0) { primeFactorList.add(i); while (num % i == 0) num = num / i; } } if (num > 1) primeFactorList.add(num); return primeFactorList; }就是和正常求质因子不同的是,这里添加了这样一个操作
while (num % i == 0) num = num / i;这就是为了求出一个因子以后,这一类的因子以后都不用再考虑了,大大缩小了num的长度,增加了效率。
此外
if (num > 1) primeFactorList.add(num);由于num大大缩小,不会像原来一样遍历完全,所以可能会漏掉num本身。
所以问题就简单了。
此外还需要考虑一个问题,两个数之间的乘积 = 两个数的最大公因数 * 两个数的最小公倍数;
(原因:假设m = a*c,n = b *c(ab互质),那么他们的公因数就是c,公倍数就是abc,乘积就是abcc,相等)
但是这个原理对多个数不适用,你们可以也一样地推一下。
所以我们应该求出互不相同质因子的乘积,再去用乘积的2倍,3倍。。一直遍历到可以把所有数的乘积整除,这样就行了,非常简单。
我把每个功能都分成了一个个小模块 十分的清晰
public class LeastCommonMultiple1019 { List<Integer> list = new ArrayList<>(); //初始化list LeastCommonMultiple1019(Integer...i) { Collections.addAll(list, i); } //把list里的每个整数都求出质因子来,放入一个新集合,再把所有的集合放入一个新的乘方集合的集合, //相当于二维数组 private List<List<Integer>> getPrimeFactor(List<Integer> list) { List<List<Integer>> allList = new ArrayList<>(); for (int i : list) { List<Integer> mList = new ArrayList<>(); int num = i; for (int j = 2; j * j < num; j ++) { if (num % j == 0) { mList.add(j); while (num % j == 0) num /= j;//一次性彻底消除一种因子 } } if (num > 1) mList.add(num); allList.add(mList); } return allList; } //根据这个“二维数组”,找出每一列存放的质因子,留下互不相同的质因子 private List<Integer> getPrimeList(List<List<Integer>> list) { List<Integer> primeList = new ArrayList<>(); for (List<Integer> mList : list) { for (int i : mList) { if (!primeList.contains(i)) { primeList.add(i); } } } return primeList; } //把互不相同的质因子,进行处理,返回结果 private int getResult(List<Integer> list) { int product = 1; for (int i : list) { product *= i; } int max = -1; for (int i : this.list) { if (max < i) { max = i; } } int i = 2; while ((product * i) % max != 0) { i ++; } return product * i; } private int getAnswer() { List<List<Integer>> list = getPrimeFactor(this.list); List<Integer> primeList = getPrimeList(list); return getResult(primeList); } public static void main(String[] args) throws Exception { LeastCommonMultiple1019 leastCommonMultiple1019 = new LeastCommonMultiple1019(6,4,10296,936,1287,792,1); int answer = leastCommonMultiple1019.getAnswer(); System.out.println(answer + ""); } }