hdu-Lowest Common Multiple Plus求多个数的的最小公倍数(瑕疵版)
Problem Description
求n个数的最小公倍数。
Input
输入包含多个测试实例,每个测试实例的开始是一个正整数n,然后是n个正整数。
Output
为每组测试数据输出它们的最小公倍数,每个测试实例的输出占一行。你可以假设最后的输出是一个32位的整数。
Sample Input
2 4 6 3 2 5 7
Sample Output
12 70
解题思路:
n个数的最小公倍数可以用质因子分解法;
例如:求10 12 4的最小公倍数(用质因数表示)
10 = 2 * 5 ..........(1)
12 = 2 * 2 *3........(2)
4 = 2 * 2...........(3)
在(1)式中有一个2,一个5;在(2)式中有两个2,一个3;在(3)式中有两个2;
所以2最多有两个,3最多有一个,5最多有一个;最后ans = ( 2 ^ 2 ) * ( 3 ^ 1 ) * ( 5 ^ 1 ) = 60
看完解题思路,就请移步到这篇博文:http://blog.youkuaiyun.com/yin_zongming/article/details/22658057
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 10000
using namespace std;
int p[maxn];//存放素数
int prime()//求出小于maxn的所有素数
{
int i,j,k=0;
for(i=2;i<=maxn;i++)
{
int flag=0;
for(j=2;j<i;j++)
{
if(i%j==0)
{
flag=1;
break;
}
}
if(flag==0)
p[k++]=i;
}
return k;
}
int main()
{
int count;
count=prime();//小于maxn的素数共有count个
int s[maxn],num[maxn];//num[]用来记录该素数出现的最多次数
int n,i,j,k,max,temp;
__int64 sum;
while(~scanf("%d",&n))
{
memset(num,0,sizeof(num));
for(i=0;i<n;i++)
{
scanf("%d",&s[i]);
for(j=0;j<count;j++)
{
max=0;
if(s[i]%p[j]==0)//看这个数是否能够分解为该质因数
{
temp=s[i];
while(1)
{
if(temp%p[j]!=0)break;
else
{
max++;//记录该质因数在这个数中出现的次数
temp/=p[j];
}
}
if(max>num[j])
num[j]=max;
}
}//这里存在一个问题就是如果对于数据量比较的大的数,我可能素数表不够用,所以我就应该加以补充。但是这里我忘记补充了,抱歉。
}//在这篇里面我有补充http://blog.youkuaiyun.com/yin_zongming/article/details/22658057
sum=1;
for(i=0;i<count;i++)
if(num[i])
for(j=0;j<num[i];j++)//对所有出现次数不为0的质因数求他们的幂的积
sum*=p[i];
printf("%I64d\n",sum);
}
return 0;
}
后来我用了另外一种方法:但是对于数据量比较大的可能会超时,注意!!
两两之间求出最小公倍数,最后得出结果。这样代码比较简短,而且便于理解。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef __int64
typedef __int64 LL;
#else
typedef long long LL;
#endif
#define maxn 10000
int num[maxn];
int gcd(int a,int b)
{
if(b==0)
return a;
return gcd(b,a%b);
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int lcmN(int s[],int len)
{
int ans;
if(len==1)
return s[0];
ans=lcm(s[0],s[1]);
for(int i=2;i<len;i++)//求出两个数之间的LCM
ans=lcm(ans,s[i]);
return ans;
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&num[i]);
printf("%d\n",lcmN(num,n));
}
return 0;
}