题目
输入整数N,计算1~N这N个数的最小公倍数,N<100
思路
思路其实很清晰,只要求得了前N-1个数的最小公倍数a,那么N个数的最小公倍数就是a和N的最小公倍数。求两个整数\(a,b\) 的最小公倍数就是 \(\frac{a\times b}{gcd(a,b)}\),\(gcd(a,b)\)为a和b的最大公约数。看起来似乎很简单,但是这里有个大坑:值越界。
题目中限制了N<100,但是当 N=23 的时候,计算得到的最小公倍数为5354228880已经远远超过了int型的表示范围。
方法一
通过质因数求解。例如对于4和10,4的质因数为(2,2),10的质因数为(2,5)。由于他们有一个公共质因数2,所以最小公倍数为2*2*5=20。
所以第一步先求所有N个数的质因数,重复的质因数只能算一次,接下来将所有质因数相乘就可以得到最小公倍数。但其实这里还是有大数的问题,所以需要通过大数相乘的方法计算,也就是通过数组保存大数。代码如下:
import java.util.Scanner;
public class Main{
public static void main(String[] arg){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[105]; // a[1]~a[N]存储 1~N 的N个数的所有质因数
int[] nums = new int[100]; // 将结果从低位到高位存在一个数组里
for(int i = 1; i <= 101; i++){
a[i] = i;
}
// 计算质因数存到a中
// 此时实质上a[1]*a[2]*...*a[N]就是1~N的最小公倍数
// 但直接相乘会数值溢出,因此用数组来进行大数相乘
for(int i = 2; i <= 101; i++){
for(int j = i + 1; j <= 101; j++){
if(a[j] % a[i] == 0){
a[j] /= a[i];
}
}
}
nums[0] = 1;
// tag存放进位,count存放有效数组长度
int tag = 0, count = 0;
for(int i = 2; i <= n; i++){
if(a[i] > 1){ // 减少不必要的计算
for(int j = 0; j <= count || tag > 0; j++){
int tmp = nums[j] * a[i] + tag;
nums[j] = tmp % 10;
tag = tmp / 10;
if(j > count){ // 更新有效长度
count = j;
}
}
}
}
while(count >= 0){ // 最后将nums中的有效数字从高位到低位输出
System.out.print(nums[count]);
count--;
}
System.out.println();
}
}
方法二
java.math包中提供了BigInteger类用来处理大整数的问题。这里用另一种思路:小于N的质数最大幂乘积的方式。
例如N=10,小于10的质数有:2,3,5,7
对应的最大幂分别为:3,2,1,1(即质数的最大幂次方小于N)
因此前1~10的最小公倍数为2^3 * 3^2 * 5 * 7 = 2520
代码如下:
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
public static void main(String[] arg){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
BigInteger ans = BigInteger.ONE;
for(int i = 2; i <= n; i++){
int tmp = 1;
if(isPrime(i)){
while(tmp * i <= n){
tmp *= i;
}
}
ans = ans.multiply(BigInteger.valueOf(tmp));
}
System.out.println(ans);
}
private static boolean isPrime(int a){
for(int i = 2; i <= Math.sqrt(a); i++){
if(a % i == 0){
return false;
}
}
return true;
}
}
参考来源
https://blog.csdn.net/sharing_li/article/details/8737855?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1
https://www.xuebuyuan.com/2857576.html