`
yzmduncan
  • 浏览: 330379 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

数论——素数筛选法与整数的素因子分解

阅读更多

筛选法   

     求出n以内的素数,最快的应该是筛选法。

 筛选法的思路是:

     要求10000以内的素数,把1-10000都列出来,1不是素数,划掉;2是素数,所有2的倍数都不是素数,划掉;取出下一个幸存的数,划掉它的所有倍数;直到所有素数找完为止。

     这种做法的空间复杂度是O(n),时间复杂度O(n/logn)。

const int Max = 1000005;
bool prime[Max]={0};//0表示素数,1为非素数

//筛选n以内的素数
void getPrime(int n)
{
    int i,j;
    int t;
    for(i = 2; i <= n; i++)
    {
        if(!prime[i])
        {
            for(j = 2; (t=j*i) <= n; j++)
                prime[t] = 1;
        }
    }
}

 

 

 

 

分解素因子

     唯一质因子分解定理:任意一个合数a仅能以一种方式,写成如下的乘积形式:

a = p1^e1*p2^e2*...*pr^er

    其中pi为素数,p1<p2<...<pr,且ei为正整数。例如数6000=2^4*3*5^3。

    素因子的分解技巧:首先a的某两个素因子不可能同时大于sqrt(a),这样,先用筛选法求出sqrt(a)以内的所有素数,然后用a依次去mod这些素数,若能整除,则找到素因子,将素因子去掉,再继续找。最后若a>1,则a也是它的素因子。

 

const int Max = 100005;
int isPrime[Max]={0};
int prime[Max/5],num=0;
int factors[100],s=0;

void getPrime(int n)
{
    int i,j;
    int t;
    for(i = 2; i <= n; i++)
    {
        if(!isPrime[i])
        {
            prime[num++] = i;
            for(j = 2; (t=i*j) <= n; j++)
                isPrime[t] = 1;
        }
    }
}

void decompose(int n, int* factors)
{
    int te = (int)sqrt(n*1.0);
    for(int i = 0; i<num&&prime[i]<=te; i++)
    {
        if(n%prime[i]==0)
        {
            factors[s++] = prime[i];
            while(n%prime[i]==0)
                n = n/prime[i];
        }
    }
    if(n > 1)
        factors[s++] = n;
}

 

 

POJ2262

题意:给出任意一个正整数n(n<=10^6),根据哥德巴赫猜想:任意一个不小于6的整数,都可以表示为两个奇素数之和。问虽任意整数是否满足这个猜想。

解:筛选法将n以内的所有素数都求出来,若a是素数,判断n-a是否为素数,若找到一组不满足,则答案为否定。

 

POJ1142

题意:给一个数n(n<=10^7),求最小的m>n,使得m的素因子每一位上的数的和 == m的每一位上的数的和。

解:显然这题就是要分解素因子。先求10^4以内的素数,再用素因子分解,然后判断。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int Max = 10005;
bool isPrime[Max]={0};
int prime[Max/4],num=0;

void getPrime(int n)
{
    int t;
    for(int i = 2; i <= n; i++)
    {
        if(isPrime[i]==0)
        {
            prime[num++] = i;
            for(int j = 2; (t=j*i) <= n; j++)
                isPrime[t] = 1;
        }
    }
}

int getSum(int n)
{
    int ret = 0;
    while(n)
    {
        ret += n%10;
        n /= 10;
    }
    return ret;
}

bool isSmith(int n)
{
    int t = (int)sqrt(n*1.0);
    int r1 = getSum(n);
    int r2 = 0;
    int N = n;
    for(int i = 0; i<num&&prime[i]<=t; i++)
    {
        if(n%prime[i]==0)
        {
            int tmpt = getSum(prime[i]);
            while(n%prime[i]==0)
            {
                n = n/prime[i];
                r2 += tmpt;
            }
        }
    }
    if(n > 1)
        r2 += getSum(n);
    if(n==N)
        return false;
    return r1==r2;
}

int main()
{
    int i;
    int n;
    getPrime(Max-1);
    while(true)
    {
        scanf("%d",&n);
        if(!n)
            break;
        for(i = n+1; ;i++)
        {
            if(isSmith(i))
                break;
        }
        printf("%d\n",i);
    }
    return 0;
}

 

1
1
分享到:
评论

相关推荐

    整数质因数分解

    质因数分解是将一个合数(大于1且不是质数的正整数)表示为其质数因子的乘积的过程。例如,30可以分解为2 × 3 × 5。这个过程对于理解数字结构、解决数学问题以及构建安全的加密系统都至关重要。 在算法设计与分析...

    sushu.zip_K.

    文件"素数筛选法素数表质因子分解.doc"暗示了解决该问题的一种可能工具——素数筛选法,比如埃拉托斯特尼筛法(Sieve of Eratosthenes),用于生成一定范围内的所有素数。素数表可以帮助快速查找m的质因子,并用于质...

    计数质数(筛选法)1

    对于较大的n值,简单的暴力计数法(即对每个数检查其是否为质数)可能会超出时间限制,因此我们需要采用更高效的方法,如筛选法(也称为埃拉托斯特尼筛法)来解决这个问题。 筛选法是一种用于找出一定范围内所有...

    ACM必看-数论

    素数的筛法及判定是指通过算法来筛选出一定范围内的所有素数或者判断一个数是否为素数的方法。最著名的筛法之一是埃拉托斯特尼筛法(Sieve of Eratosthenes),它可以高效地找出小于或等于给定数N的所有素数。而判断...

    ACM数论(挺好理解的)

    **欧拉定理**是数论中的一个重要结果,它描述了当a与n互质时,\(a^{\phi(n)} \equiv 1 \mod n\),其中\(\phi(n)\)是欧拉函数,表示小于等于n且与n互质的正整数个数。 - **完全剩余系**: 完全剩余系指的是从模m的...

    数论算法_艾孜尔江编.pdf

    接着,文件介绍了素数的求法,这包括了两种方法:一种是判断小范围内的整数是否为质数,另一种则是构造一个素数表,用于判断更大范围内的数是否为素数。判断质数的方法是,从2开始试除到该数的平方根。这是因为如果...

    第7章 数组-7数组的其他应用——筛法求素数1

    【筛法求素数】是计算数学中一种高效找出一定范围内所有素数的方法,尤其适用于在数组中批量处理。在C语言程序设计中,我们通常使用这种方法来解决如何判断一个整数是否为素数的问题。 首先,素数是大于1且只能被1...

    《算法竞赛中的初等数论》(一)正文 0x00整除、0x10 整除相关(ACM _ OI _ MO)(十五万字符数论书)1

    试除法是最直观的,但效率较低,需要尝试从2到√n的所有整数因子。为了提高效率,可以采用埃拉托斯特尼筛法(Sieve of Eratosthenes),它是一种预先筛选出所有素数的方法。此外,还有 Miller-Rabin素数检验,这是一...

    数论模板精心整编

    素因子分解通常采用试除法,即从最小的质数开始,依次尝试除以给定的数,直至无法继续除尽为止。具体实现代码如下: ```c++ bool is_prime(int n) { if (n ) return false; if (n ) return true; if (n % 2 == 0...

    线性筛法求素数的原理与实现

    ### 线性筛法求素数的原理与实现 #### 一、线性筛法的概念及优势 线性筛法是一种高效的算法,能够在O(n)的时间复杂度内找到所有不大于n的素数。相比于传统的遍历取余判断素数的方法,线性筛法在需要频繁判断素数的...

    算法-数论- 概述.rar

    5. 图论与组合优化:Eratosthenes筛法是寻找质数的一种高效算法,它利用数论性质筛选掉非质数,常用于解决组合优化问题。 6. 数学证明:费马大定理和黎曼猜想等著名数论问题的探讨,启发了新的算法思想和证明技术,...

    数论算法模板

    结合素数筛选与欧拉函数计算,可以在较大范围内高效计算欧拉函数值和识别素数。 #### 7. 求解a*x=b mod n 这是求解线性同余方程的问题,通常涉及到扩展欧几里得算法。 #### 8. 求解gcd(a,b)=a*x+b*y 扩展...

    zhenyinzi.rar_真因子

    3. **因数分解法**:通过分解n的质因数,可以快速找出所有真因子。例如,如果n = 2^a * 3^b * 5^c...,那么所有可能的真因子组合就是2^i * 3^j * 5^k...,其中0≤i≤a, 0≤j≤b, 0≤k≤c...。 4. **轮换法**:对于...

    2016数论.pptx

    - **因式分解唯一性**:每个整数(\(n \geq 2\))都可以被唯一地分解为若干素数的乘积。 - **素因子个数的上界**:一个数\(n\)的素因子个数不超过\(\log_2 n\)。 - **素数分布**:在1至\(n\)中,素数大约有\(n / \ln...

    质数的判断条件.zip说明

    - **埃拉托斯特尼筛法**:用于找出一定范围内所有质数的算法,通过逐步筛选掉非质数,留下质数。 - **AKS素性测试**:2002年提出的确定性算法,能够在多项式时间内判断一个数是否为质数,但实际应用中不如试除法和...

    ACM的数论.....

    另一种是埃拉托斯特尼筛法,从2开始,依次筛选出所有素数的倍数,留下的未被筛选的就是素数。 此外,除法定理和余数是数论中的基础工具。除法定理指出,对任何整数a和正整数n,存在唯一整数q和r,使得a=qn+r,其中0...

    素数判定的几种算法范文

    简单筛选法适合小规模教育场景,平方根遍历法和素数筛法适合中等规模的素数检测,而Rabin-Miller算法则是处理大数素性检验的高效工具。在实际应用中,为了提高性能,还可以结合其他优化策略,如提前计算小范围内的...

    表整数为两个互素的无平方因子数的和 (2008年)

    具体地,可以利用Möbius函数和筛选法的思想来推导出\( |Q_1(n)| \)的渐进表达式。该公式的形式通常较为复杂,但可以有效地估计出随着\( n \)增大时\( |Q_1(n)| \)的增长趋势。 #### 4. 证明过程 论文中进一步利用...

    五年级分解质因数PPT学习教案.pptx

    总结:本资料是针对五年级学生设计的关于分解质因数的PPT学习教案,主要涵盖了质数和合数的基本概念,如何判断质数与合数,分解质因数的原理及方法,以及通过短除法进行质因数分解的技巧。此外,还包括了数的筛选...

    质数(素数)计算

    质数(素数)是数学领域的一个重要概念,指大于1且仅能被1和它自身整除的正整数。在计算机科学中,尤其是在密码学、算法设计和数论等领域,质数计算扮演着至关重要的角色。这篇讨论将聚焦于如何在Delphi编程环境中...

Global site tag (gtag.js) - Google Analytics