时间限制: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
来源
2011蓝桥杯
想法:大数+数论
首先我们要知道1....n的最小公倍数是怎么来的。
下面的说法可能不正确,但好理解。
容易知道公倍数可由1*2*..N得到
那最小公倍数则要在之前的基础上约去1到n大的中公因数
于是可得1到n的因数
原数1 2 3 4 5 6 7 8 。。。n
因数1 2 3 2 5 1 7 2 。。。。
公因数- - - 2 - 2,3 - 2,2 。。。
上面1到8中 4之前有2 6之前有2,3 8有前面2,2
依次类推
从而很方便求得1到n的最小公倍数
注意得到的可以是大数,要进行大数处理
代码:
#include<stdio.h>
#include<string.h>
int factor[101];
char ans[105][100];
void getfactor()//求出因数
{
for(int i=1;i<=100;i++)
{
factor[i]=i;
for(int j=2;j<i;j++)
if(factor[i]%factor[j]==0)
factor[i]=factor[i]/factor[j];
}
}
void bigmul()//相乘
{
int sum,k=0,j,b;
ans[1][0]='1';
ans[1][1]='\0';
for(int i=2;i<=100;i++)
{
b=factor[i];
for(j=0,k=0;j<strlen(ans[i-1]);j++)
{
sum=(ans[i-1][j]-'0')*b+k;
k=sum/10;
ans[i][j]=sum%10+'0';
}
while(k)
{
ans[i][j]=k%10+'0';
k/=10;
j++;
}
}
}
void print(int n)//输出前N为最小公倍数
{
for(int i=strlen(ans[n])-1;i>=0;i--)
printf("%c",ans[n][i]);
printf("\n");
}
int main()
{
getfactor();
bigmul();
int n;
while(scanf("%d",&n)!=EOF)
{
print(n);
}
return 0;
}