自学内容网 自学内容网

「数学::质数」试除法 / Luogu P5736(C++)

概述

在质数的第一节我们来讲解试除法。

质数是指在大于1的自然数中只能被1和它自己整除的数。

我们可以利用这一除法性质对质数进行判定。

Luogu P5736:

输入 n 个不大于 10^5 的正整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。

思路

如果一个数不是质数,即合数,那么它一定可以被除1和它自己以外的数整除。

如果有合数a,那么必有a%b==0。其中b!=a&&b!=1。

因此对于一个数x,因此我们可以从2开始枚举自然数到x-1,判断其中是否有可以整除x的数,如果有,则x不是质数。

但是对于单个数n进行判断,这样做的时间复杂度就已经是O(n)级别的了,该怎么优化呢?

注意到:如果a是合数,b是a的一个因数,则c=a/b也是a的一个因数。

因此对于一对数(b,a/b),只需要检验其中较小的那个是否是a的因数即可,即min(b,a/b)。

当b=c时,√a=b=c,即较小的因数最大为√a,所以我们只需要枚举[2,√a]就能断定a是否为质数。

综上:

如果x是一个合数,那么枚举[2,√x]就能检验出其为合数。

如果x是一个质数,那么枚举[2,√x]时就没有任何一个数整除它,那么[√x,x)必然不能整除它,不必检验。(因数是成对出现的,小的分布在[2,√x],大的分布在[√x,x),小的不存在则大的一定不存在)

算法过程

我们来实现质数判断函数。

 很直观的代码:

bool is_prime(int& num){
    if(num<2)return false;
    for(int i=2;i*i<=num;i++)
        if(!(num%i))return false;
    return true;
}

小于2的数不是质数。

对于大于2的数,枚举从2开始的自然数,他们在[2,√x]之间,num一旦被整除就返回false,否则返回true。

复杂度

时间复杂度: O(√n)
空间复杂度: O(1)

Code

#include <iostream>
using namespace std;
bool is_prime(int& num){
    if(num<2)return false;
    for(int i=2;i*i<=num;i++)
        if(!(num%i))return false;
    return true;
}
int main(){
    int n;cin>>n;
    int num,cnt=0,ans[n]={0,};
    while(n--){
        cin>>num;
        if(is_prime(num))ans[cnt++]=num;
    }
    for(int i=0;i<cnt;i++)cout<<ans[i]<<' ';
    return 0;
}

原文地址:https://blog.csdn.net/dakingffo/article/details/141999668

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!