zoukankan      html  css  js  c++  java
  • 51nod 1434 理解lcm

    题目来源: TopCoder
    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     收藏
     关注
    一个整数序列S的LCM(最小公倍数)是指最小的正整数X使得它是序列S中所有元素的倍数,那么LCM(S)=X。
    例如,LCM(2)=2,LCM(4,6)=12,LCM(1,2,3,4,5)=60。
    现在给定一个整数N(1<=N<=1000000),需要找到一个整数M,满足M>N,同时LCM(1,2,3,4,...,N-1,N) 整除 LCM(N+1,N+2,....,M-1,M),即LCM(N+1,N+2,....,M-1,M)是LCM(1,2,3,4,...,N-1,N) 的倍数.求最小的M值。
    Input
    多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5
    每组测试数据有相同的结构构成:
    每组数据一行一个整数N,1<=N<=1000000。
    
    Output
    每组数据一行输出,即M的最小值。
    
    Input示例
    3
    1
    2
    3
    
    Output示例
    2
    4
    6
    lcm是最小公倍数。2个数的最小公倍数代表着什么呢? 其实就是2个数他们的质因子一定有公有部分(有的只有1)。
    那么公有部分只需要取一次,其它非公有的都相乘,这个数就是最小公倍数。所以这里就是要找到一个m,使m尽量小,
    让m都包含1~n里所有质因子的最高次方,这时候只需要对于每一个质因子,找到x,使x*prime[i](当前质因子) <= n,
    然后x乘上最小的一个值后,x > n,这是候这个x就是满足的其中一个值。这是只需要遍历一下所有情况就能得到最小的m。
     
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<string>
    #include<time.h>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 1<<30
    #define ll unsigned long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define MOD 1000000007
    using namespace std;
    const int MAXN = 1000010;
    ll n;
    int a[MAXN],cnt,numa[MAXN];
    int isnotprime[MAXN],num;
    ll prime[MAXN];
    void Init()
    {
        num = 0;
        memset(isnotprime,0,sizeof(isnotprime));
        for(int i = 2; i <= MAXN - 5; i++){
            if(!isnotprime[i]){
                prime[num++] = i;
            }
            for(int j = 0; j < num && 1LL * i * prime[j] < MAXN; j++){
                isnotprime[i*prime[j]] = 1;
                if(i % prime[j] == 0)break;
            }
        }
    }
    void solve()
    {
        if(n == 1){
            cout<<2<<endl;
            return ;
        }
        ll ans = 0;
        for(int i = 0; i < num; i++){
            if(prime[i] > n)break;
            ll ret = 1;
            while(ret * prime[i] <= n){
                ret *= prime[i];
            }
            for(int j = 2; ; j++){
                if(ret * j > n){
                    ret *= j;
                    break;
                }
            }
            ans = max(ans,ret);
        }
        cout<<ans<<endl;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        Init();
        while(t--){
            scanf("%d",&n);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    ZedGrapy使用实例
    C#分割字符串(包括使用字符串分割)
    从VS2005项目转换为VS2008项目(C#版)
    关于SQL操作的一些经验
    android socket 编程总结
    Excel绘制人口金字塔图
    使用命令让IE全屏显示指定的页面,适用于触摸屏终端机
    毕业这两年
    使用XML数据结合XSLT导出Excel
    XSLT实现XML作为数据源在web页面显示人口金字塔统计图
  • 原文地址:https://www.cnblogs.com/sweat123/p/5503290.html
Copyright © 2011-2022 走看看