输入n,求出1~n的所有数的最小公倍数:
例如 n = 6 时,为12325 = 60.
思路:双层循环检验每个数是否为其他数的因子,比如4和2,2是4的因子,4就可以约去一个2变成2,所有的数去掉因子之后相乘即最小公倍数。
数相乘这里用数组存储,因为相乘可能造成结果很大,需要用数组进行存储。
大数相乘:数据从数组的尾部进行存储,一点点往前扩展。每次记录当前的进位,留到下一位运算时相加(类似于手算过程)。
#include<bits/stdc++.h>
using namespace std;
#define MAX 105 //1~n存储的数组大小
#define MAXSUM 100000 //存储结果的数组大小
int sum[MAXSUM]; //存储结果的数组
int len; //存储结果的数组的空白长度(未存数据时为MAXSUM)
void big_mul(int n){//大数相乘
int high = 0;
for (int i = MAXSUM-1; i>=len;i--){
sum[i] = sum[i]* n + high;//先相乘再加上上一位的进位
high = sum[i]/10;//进位
sum[i] =sum[i]%10;
}
if(high != 0){//有进位
sum[len-1] = high;
len--;//空位减少
}
}
int main(){
int a[MAX];//存储1~n
int n;
while(cin>>n){//循环输入n
for(int i = 1; i<=n; i++){
a[i] = i;//1~n
}
for(int i = 2; i<n; i++){
for(int j = i+1; j<=n; j++){
if(a[j]%a[i] == 0){//寻找因子
a[j] = a[j]/a[i];
}
}
}
sum[MAXSUM-1] = 1;//初始化为000...1
len = MAXSUM-1; //记录前面空白也就是0的长度
for(int i = 1; i<= n; i++){
big_mul(a[i]);//sum数组与a[i]进行相乘
}
for(int i = len; i<MAXSUM;i++){
cout<<sum[i]<<" ";//输出结果
}
cout<<endl;
}
return 0;
}
注:
空白的长度就是数组前面为空的长度,比如0006,那么len=3,当0006*2时,有进位high = 1,循环终止条件i>=len,跳出循环后,把进位存入sum[len-1]的位置,也就是前面空白少了一个位置,变成0012。
再贴一个java的求法,简单多了:
import java.math.BigInteger;
public class Main
{
// 求能除尽1~n 每个数字的最小整数
public static BigInteger f(int n)
{
int[] x = new int[n+1];
for(int i=1; i<=n; i++) x[i] = i;
for(int i=2; i<n; i++)
{
for(int j=i+1; j<=n; j++)
{
if(x[j] % x[i]==0)
x[j]=x[j]/x[i];
}
}
//解决大数相乘
BigInteger m = BigInteger.ONE;
for(int i=2; i<=n; i++)
{
m = m.multiply(BigInteger.valueOf((long)x[i]));
}
return m;
}
public static void main(String[] args)
{
System.out.println(f(100));
}
}