http://acm.nyist.net/JudgeOnline/problem.php?pid=517

因为任意一个整数n可以表示为n=p1^a1*p2^a2.......所以只需要取每一个素因子数最多的那个ai相乘即可。。。。

最小公倍数

时间限制: 1000 ms | 内存限制: 65535 KB
难度: 3
描述
为什么1小时有60分钟,而不是100分钟呢?这是历史上的习惯导致。
但也并非纯粹的偶然:60是个优秀的数字,它的因子比较多。
事实上,它是1至6的每个数字的倍数。即1,2,3,4,5,6都是可以除尽60。

我们希望寻找到能除尽1至n的的每个数字的最小整数m.
输入
多组测试数据(少于500组)。
每行只有一个数n(1<=n<=100).
输出
输出相应的m。
样例输入
2
3
4
样例输出
2
6
12
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<iostream>
#define N 101
using namespace std;
int prim[25]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};
int num[N];
int ans[N];
void doit(int n)
{memset(num,0,sizeof(num));
	for(int i=2;i<=n;++i)
	{   int p=i;
		for(int j=0;j<25&&prim[j]*prim[j]<=p&&p!=-1;++j)
		{
			int cnt=0;
			while(p%prim[j]==0)
			{
				cnt++;
				p/=prim[j];
			}
			if(cnt>num[prim[j]]) num[prim[j]]=cnt;
		}
		if(p!=1&&num[p]<1) num[p]=1;
	}
}
int ceil(int n,int len)
{
	for(int i=0;i<25;++i)
	{   
		if(num[prim[i]])
		{ 
			int p=(int)pow((double)prim[i],num[prim[i]]);
			int carry=0;
			for(int j=0;j<=len;++j)
			{
				ans[j]=ans[j]*p+carry;
				carry=ans[j]/10;
				ans[j]=ans[j]%10;
				if(j==len&&carry!=0) len++;
			}
		}
	}
	return len;
}
int main()
{  int n;
  while(~scanf("%d",&n))
  {  memset(ans,0,sizeof(ans));
	  ans[0]=1;
	  doit(n);
	  int len=ceil(n,0);
	  while(len>=0) printf("%d",ans[len--]);
	  printf("\n");
  }return 0;
}


你可能感兴趣的:(http://acm.nyist.net/JudgeOnline/problem.php?pid=517)