zoukankan      html  css  js  c++  java
  • 线性筛 埃式筛 欧拉筛

    线性筛法求素数

    题目:给出一个正整数n,打印出所有从1~n的素数(即质数);

    普通解法

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    bool isprime(int n)
    {
        if (n == 0 || n == 1)return false;
        for (int i = 2; i <=sqrt(n); i++)
            if (n%i == 0)return false;
        return true;
    }
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i <=n; i++)
        {
            if (isprime(i))printf(" %d", i);
        }
    }

    埃拉托斯特尼筛法

    算法思路:算法从小到大枚举所有数,对于每一个素数,筛去它的所有倍数,剩下的就都是素数了。

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    bool p[1000];//是否被筛去,默认为false
    int prime[1000], cnt = 0;
    void findprime(int n)
    {
        for (int i = 2; i <= n; i++)
        {
            if (!p[i])//没有被筛去的话
            {
                prime[cnt++] = i;//素数加1,
                for (int j = i + i; j <= n; j += i)//int j = i + i:从2开始,但是不能筛去2,所以从4开始
                    p[j] = true;//筛去素数的倍数
            }
        }
    
    }
    int main()
    {
        int n;
        scanf("%d", &n);
        findprime(n);
        for (int i = 0; i <cnt; i++)
        {
            printf(" %d", prime[i]);
        }
    }

    欧拉筛

    算法思路:在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    bool p[1000];
    int prime[1000], cnt = 0;
    void findprime(int n)
    {
        for (int i = 2; i <= n; i++)
        {
            if (!p[i])//未筛去的话
                prime[cnt++] = i;//素数记录
    
            for (int j = 0; j < cnt; j++)
            {
                if (i*prime[j] <= n)//用i作为倍数,筛去prime[j]中的素数的倍数
                {
                    p[i*prime[j]] = true;
                    if (i%prime[j] == 0)break;
                    //例子:i = 8 ,j = 1,prime[j] = 2,如果不跳出循环,prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会计算。
                }
            }
                    
        }
    
    }
    int main()
    {
        int n;
        scanf("%d", &n);
        findprime(n);
        for (int i = 0; i <cnt; i++)
        {
            printf(" %d", prime[i]);
        }
    }
  • 相关阅读:
    数据结构学习(一)、线性表
    内容太多用省略号代替、内容不换行,鼠标移上去显示详情
    时间格式化
    51Nod--1018排序
    51Nod--1085背包问题
    51Nod--1049最大子段和
    51Nod--1051最大子矩阵和(DP入门)
    POj1852--Ants
    c# static用法
    group by用法
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12811300.html
Copyright © 2011-2022 走看看