南阳acm517 最小公倍数(大数+数论)

来源:互联网 发布:知乎 北京 中科院 编辑:程序博客网 时间:2024/06/07 01:59
最小公倍数
时间限制: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;  
}






原创粉丝点击