质数筛法:朴素素数筛,埃氏筛,欧式筛

若一个数可以进行因数分解,则得到的两个数一定是有一个>=sqrt(x),另一个<=sqrt(x).

朴素算法

这个算法是最简单的素数判断算法+遍历素组,耗时长

bool judge(ll x)
{   
    if(x==2) return true;
    if(x<2||x%2==0)
        return false;   
    for(int i=3;i<=sqrt(x+1);i+=2)//这个地方可以优化一下,一个是范围,一个是步长 (素数一定是奇数) 
        {
            if(x%i==0)
                return false;
        }
    return true;
}

埃氏筛

在这里插入图片描述
利用当前已经找到的素数,从后面的数中筛去当前素数的倍数,当前素数已经是筛去数的质因子,如此下去能筛除之后所有的合数,是一种比较快的筛法
美中不足是会筛除多次比如8和16,同时被2和4筛去
在这里插入图片描述
输入数据
100 2
2
91
输出数据
Yes
No

#include <bits/stdc++.h>
using namespace std;
int prime[10000005];
const int N = 10000000;
void isprime()
{
    fill(prime,prime + N,true);
    prime[1] = false;
    for(int i = 2; i <= N; ++i)
    {
        if(prime[i])
        {
            for(int j = i * 2;j <= N;j += i)
            {
                prime[j] = false;
            }
        }
    }
}
int main()
{
    isprime();
    int n,m;
    cin>>n>>m;
    int num;
    for(int i = 0;i < m;i++)
    {
        cin>>num;
        if(prime[num])
            cout<<"Yes\n";
        else
            cout<<"No\n";
    }
    return 0;
}

欧式筛

这是一种很好的线性筛法,和埃氏筛法的区别是对于每一个要筛除的数,欧拉筛法只筛除一次。原理如下
任何一个合数都可以表示成一个质数和一个数的乘积
假设A是一个合数,且A = x * y,这里x也是一个合数,那么有:
A = x * y; (假设y是质数,x合数)
x = a * b; (假设a是质数,且a < x——>>a<y)
-> A = a b y = a Z (Z = b y)
即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积,那样我们到每一个数,都处理一次,这样处理的次数是很少的,因此可以在线性时间内得到解。

#include <bits/stdc++.h>
using namespace std;
int prime[10000005];
int primesize = 0;
bool isprime[10000005];
void getlist(int listsize)
{
    memset(isprime,1,sizeof(isprime));
    isprime[1] = false;
    for(int i = 2;i <= listsize;i++)
    {
        if(isprime[i])
        {
            prime[++primesize] = i;
        }
        for(int j = 1;j <= primesize && i * prime[j] <= listsize;j++)
        {
            isprime[i * prime[j]] = false;
            if(i%prime[j] == 0)
                break;
        }
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    getlist(n);
    int num;
    for(int i = 0;i < m;i++)
    {
        cin>>num;
        if(isprime[num])
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
}
发布了60 篇原创文章 · 获赞 22 · 访问量 6985

猜你喜欢

转载自blog.csdn.net/weixin_43786143/article/details/88881916