zoukankan      html  css  js  c++  java
  • UVa 10791 和最小的LCM (质因数分解)

    题意:

    输入正整数n(n<=2^31-1),找到至少两个正整数,使得他们的LCM为n,并且和是最小。

    分析:

    这题昨天做的,WA的我一脸懵逼QAQ,刚刚又看了下,原来我看成了是两个整数,把至少这俩字漏看了QAQ。
    如果是至少两个数的话,那么就非常简单了,只需要把质因数(次方)求和即可(因为可以是很多数的LCM)
    此题需注意的情况:
    (1)当N = 1时,应输出2(1*1=1,sum=1+1=2);
    (3)当只有单质因子时,sum=质因子相应次方+1;
    (4)当N=2147483647时,它是一个素数,此时输出2147483648,但是它超过int范围,应考虑用long long。

    代码:

    typedef long long ll;
    
    ll num[33];
    int main()
    {
        ll n;
        int cas=0,tot;
        while(~scanf("%lld",&n)&&n){
            printf("Case %d: ",++cas);
            if(n==1){
                puts("2");continue;
            }
            tot=0;
            for(ll i=2;i*i<=n;i++){
                if(n%i==0){
                    num[tot]=1;
                    while(n%i==0){
                        num[tot]*=i;
                        n/=i;
                    }
                    tot++;
                }
            }
            if(n>1)num[tot++]=n;
            if(tot<2){
                printf("%lld
    ",num[0]+1);continue;
            }
            ll ans=0;
            for(int i=0;i<tot;i++)ans+=num[i];
    
            printf("%lld
    ",ans);
        }
        return 0;
    }

    把题目变一下:找到两个正整数,使得他们的LCM为n,并且和是最小。
    分析:
    因为要求是两个整数的LCM,所以要把分解得到的质因子(次方)分成两组,两组求积得到两个数,使这两个数的和最小。那怎么分组呢?显然让两组的积尽量的接近可以使所得和最小,那么用优先队列去维护一下分组就行。

    typedef long long ll;
    
    ll num[33];
    int main()
    {
        ll n;
        int cas=0,tot;
        while(~scanf("%lld",&n)&&n){
            printf("Case %d: ",++cas);
            if(n==1){
                puts("2");continue;
            }
            tot=0;
            priority_queue<ll,vector<ll>,greater<ll> >q;
            for(ll i=2;i*i<=n;i++){
                if(n%i==0){
                    num[tot]=1;
                    while(n%i==0){
                        num[tot]*=i;
                        n/=i;
                    }
                    tot++;
                }
            }
            if(n>1)num[tot++]=n;
            if(tot<2){
                printf("%lld
    ",num[0]+1);continue;
            }
            for(int i=0;i<tot;i++)q.push(num[i]);
            while(q.size()>2){
                ll a1=q.top();q.pop();
                ll a2=q.top();q.pop();
                q.push(a1*a2);
            }
            ll a1=q.top();q.pop();
            ll a2=q.top();q.pop();
            printf("%lld
    ",a1+a2);
        }
        return 0;
    }
  • 相关阅读:
    分层图(了解一下,下一道比较好做)
    图论---The Captain
    数论
    NOIp复习计划
    20201116 Day4 卢卡斯定理
    20201113 Day3 斜率优化
    20201110Day2 分块
    20201030 day50 复习13:逆元、裴蜀定理
    20201030day50 模板全掌握
    20201029 day49 模拟(十八)
  • 原文地址:https://www.cnblogs.com/01world/p/5762805.html
Copyright © 2011-2022 走看看