1. 程式人生 > >歐拉項目第三題之最大質數因子

歐拉項目第三題之最大質數因子

結束 last 之一 src typedef 我們 define 是不是 fine

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\n",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

歐拉項目第三題之最大質數因子