• 欧拉项目第三题之最大质数因子


    13195的质数因子有5,7,13和29.

    600851475143的最大质数因子是多少?

    这里可以肯定的是:1.数字很大,绝对不能暴力。2.如果这是一到OJ题,那么我们的目的就是尽量缩小这个数,减少计算量。

    我们都知道,任何一个合数都是可以由他的所有质因素相乘得到的,比如15=3*3*3*3*3,12=2*2*3,60=2*2*3*5.(这些数都是我随便想的),好的,我们先看一个比较小的数60,现在我们要找它的最大质因子,我们可以从最小的奇数开始枚举(当然要先枚举2这个特殊的质数,除此之外的偶数可能是质数吗?),如果可以整除说明这个奇数是其因子之一,然后判断这个奇数如果是质数,那么它就是其中一个质因子。然后原数就可以除这个因子了,为了排除已经找到的因子,我们一直将它除这个数,直到不能整除,60/=2得30,30/=2得15,到此结束此因子,我们就找到了2这个质因子;同理,到3的时候15/=3得5,找到了3这个质因子;5/5=1,可以结束,5就是我们要找的最大质因子啦。如果是多测试的话一直频繁判断素数是不是有点不爽?所以我们可以打个素数表- -。还有一个优化就是这个素数不会超过sqrt(n),可以减少循环次数,至于证明自己搜吧。

    附上我的AC代码:

    #include<stdio.h>
    #include<map>
    #include<math.h>
    using namespace std;
    #define ll long long
    #define MAX 600851475143
    map<ll,bool> is;
    map<ll,ll> pr;
    void init()
    {
        ll t=(ll)sqrt(10000000),i,j,p=0;
        for(i=2 ; i<= t ;i++)
            is[i]=true;
        for(int i=2 ; i<=t ; i++)
        {
            if(is[i]==true)
            {
                pr[p]=i;
                p++;
                for(j=2*i ; j<=t ; j+=i)
                    is[j]=false;
            }
        }
    }
    ll sove()
    {
        ll m=(ll)sqrt(MAX);
        ll num=MAX;
        ll ans,la,i,f;
        if((num&1)==0)
        {
            la=2;
            num>>=1;
            while((num&1)==0)
                num>>=1;
        }
        else
            la=1;
        f=3;
        for(i=1 ; num>1 &&f<m;i++)
        {
            f = pr[i];
            if(num%f==0)
            {
                num/=f;
                la=f;
                while(num%f==0)
                    num/=f;
                m=(ll)sqrt(num);
            }
        }
        if(num==1)
            return la;
        else
            return num;
    }
    int main()
    {
        init();
        printf("%lld
    ",sove());
    }
    View Code

    谨防出错附上大神AC代码:

    #include<bits/stdc++.h>
    
    
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    
    const int MAXN = 100000000;
    int prime[MAXN],cnt_prime=0;
    bool isprime[MAXN];
    
    
    
    void GetPrime(int MAX)
    {
        memset(isprime,0,sizeof(isprime));
        int m=(int)sqrt((double)MAX);
    
        for(int i=2;i<=m;i++)
        {
            if(!isprime[i])
            {
                for(int j=i*i;j<=MAX;j+=i)
                {
                    isprime[j]=1;
                }
            }
        }
    
        cnt_prime=0;
        for(int i=2;i<=MAX;i++)
        {
            if(!isprime[i])
            {
                prime[cnt_prime++]=i;
            }
        }
    }
    
    int findit(ull num)
    {
        ull m = (int)sqrt(double(num));
        ull lastf,f;
        if((num&1)==0)
        {
            lastf = 2;
            num>>=1;
            while((num&1)==0)
                num>>=1;
        }
        else
            lastf = 1;
    
        f=3;
        for(int i = 2; num > 1 && f < m; i++)
        {
            f = prime[i];
            if(num % f == 0)
            {
                num /= f;
                lastf = f;
                while(num%f==0)
                    num/=f;
                m=(int)sqrt(double(num));
            }
        }
    
        if(num==1)
            return lastf;
        else
            return num;
    }
    
    int main()
    {
    
        GetPrime(10000000);
    
        cout<<findit(600851475143)<<endl;
        
    }
    View Code
  • 相关阅读:
    Linux:mv命令
    Linux:cp -rp
    Linux:sed命令
    Linux:cut命令...未完待续
    Linux:xargs命令
    python动态获取对象的属性和方法 (转载)
    python 继承中的super
    HTTP认证机制(翻译)
    技术名词解释
    设计模式之代理模式
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9016820.html
Copyright © 2020-2023  润新知