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

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());
}

谨防出错附上大神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;

}

原文地址:https://www.cnblogs.com/shuaihui520/p/9016820.html

时间: 2024-09-29 22:58:01

欧拉项目第三题之最大质数因子的相关文章

欧拉项目第十题;用筛法做,

#include<stdio.h>#define N 2000000int a[N]; int main(){ __int64 sum=0; __int64 i,j; for(i=2;i<N;i++) a[i]=1; for(i=2;i<N;i++) if(a[i]) for(j=i;i*j<N;j++) a[i*j]=0; for(i=2;i<N;i++) if(a[i]) sum=sum+i; printf("%I64d",sum); retur

欧拉项目004:寻找最大的回文数

Problem 4: Largest palindrome product A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99. Find the largest palindrome made from the product of two 3-digit numbers. 寻找有两

欧拉项目005:最小公倍数

Smallest multiple Problem 5 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? 就是找出1....20 所有数的最

006:欧拉项目平方和与和的平方的差

Sum square difference Problem 6 The sum of the squares of the first ten natural numbers is, 12 + 22 + ... + 102 = 385 The square of the sum of the first ten natural numbers is, (1 + 2 + ... + 10)2 = 552 = 3025 Hence the difference between the sum of

欧拉项目007:第10001个素数

10001st prime Problem 7 By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10 001st prime number? 使用埃拉托斯特尼筛法,不懂得自行Wiki 我的python代码: # -*- coding:utf-8 -*- #使用埃拉托斯尼特晒法 #从2开始 import math def

欧拉工程第70题:Totient permutation

题目链接 和上面几题差不多的 Euler's Totient function, φ(n) [sometimes called the phi function]:小于等于n的数并且和n是互质的数的个数 存在这样的数:N的欧拉数φ(n),是N的一个排列 例如:φ(87109)=79180 求在1---10^7中n/φ(n) 取到最小的 n 是多少? 这里的是p是n的素因子,当素因子有相同的时候只取一个 任意一个正整数都能分解成若干个素数乘积的形式 直接利用上题的phi函数就可以求解 这个是跑的最

欧拉筛——$\Theta(n)$复杂度的质数筛法

欧拉筛法可以以\(\Theta(n)\)的时间,空间复杂度求出\(1-n\)范围内的所有质数. 其核心思想是每个合数仅会被其最小的质因数筛去一次. See this website for more details. ```cpp #include <iostream> #include <cstdio> using namespace std; const int MAXN(1000001); int n_prime(0); bool not_prime[MAXN]; int p

欧拉工程第51题:Prime digit replacements

题目链接 题目: 通过置换*3的第一位得到的9个数中,有六个是质数:13,23,43,53,73和83. 通过用同样的数字置换56**3的第三位和第四位,这个五位数是第一个能够得到七个质数的数字,得到的质数是:56003, 56113, 56333, 56443, 56663, 56773, 和 56993.因此其中最小的56003就是具有这个性质的最小的质数. 找出最小的质数,通过用同样的数字置换其中的一部分(不一定是相邻的部分),能够得到八个质数. 解题思想: 这个题目是很难的 你首先要找到

欧拉项目代码(1--7)

第七题 求第10001个质数(用这个代码,我的笔记本大概算了40s): count=1 num=3 def findPrime(s): i=2 a=s while i<s/2: if s%i == 0: s=s/i break else: i=i+1 if s==a: return True else: return False while count <10001: if findPrime(num): count =count + 1 num = num +2 else: num = nu