• 欧拉筛找素数


    任何合数都可以表示为多个素数的乘积,合数肯定有一个最小的质因子,通过这个最小质因子筛掉合数,保留素数。

    Aizu0009:求小于或等于n的素数个数 n∈[1,999999]

    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<cstring>
    using namespace std;
    const int maxa=1000010;
    int prime[maxa];
    bool flag[maxa];
    int cnt,n;
    
    void find_prime()
    {
            cnt=0;
            memset(flag,true,sizeof(flag));
            flag[0]=flag[1]=false;
            for(int i=2;i<=n;i++)
            {
                if(flag[i])
                    prime[cnt++]=i;
                for(int j=0; j<cnt&&prime[j]*i<=n; j++)
                {
                    flag[i*prime[j]]=false;   ///如果n足够大,每次最少筛一个
                    if(i%prime[j]==0) break;    ///prime[j]必定是prime[j]*i和i的最小质因子
                ///比如i=4,筛掉8之后就停止了,不会筛4*3=12,12留给i=6的时候去筛,当i=6时,筛掉12,不会筛i*3=18,留给i=9的时候去筛
                ///i=9时,筛掉18之后,再筛掉27,不会筛5*9=45,45留给i=15去筛,i=15时,筛掉30和45,不会筛掉75,75留给i=25筛
                ///很明显,是通过最小质因数来筛掉合数的,而且保证不会重复筛,降低了时间复杂度
                }
            }
            cout<<cnt<<endl;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            find_prime();
        }
    }
    
    /*
    模拟欧拉筛:
    判断25以内的素数
    数字 1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23  24   25
    判断 f           f       f       f   f    f         f         f    f    f        f          f    f   f        f       f
    i=2;i<=25;    yes;prime[0]=2;cnt=1;
    for
    j=0;j<1 && 2*2<=25;        flag[4]=false; if(2%prime[0]==0) yes break;
    j=1;j<1 && no
    
    i=3;i<=25;  yes;prime[1]=3;cnt=2;
    for
    j=0;j<2 && 2*3<=25;        flag[6]=false; if(3%prime[0]==0) no
    j=1;j<2 && 3*3<=25;        flag[9]=false; if(3%prime[1]==0) yes break;
    
    i=4;i<=25;  no;
    for
    j=0;j<2 && 2*4<=25;        flag[8]=false; if(4%prime[0]==0) yes break;
    
    i=5;i<=25;  yes;prime[2]=5;cnt=3;
    for
    j=0;j<3 && 2*5<=25;        flag[10]=false; if(5%prime[0]==0) no
    j=1;j<3 && 3*5<=25;        flag[15]=false;    if(5%prime[1]==0) no
    j=2;j<3 && 5*5<=25;        flag[25]=false; if(5%prime[2]==0) yes break;
    
    i=6;i<=25;  no;
    for
    j=0;j<3 && 2*6<=25;        flag[12]=false; if(6%prime[0]==0) yes;break;
    
    i=7;i<=25;    yes;prime[3]=7;cnt=4
    for
    j=0;j<4 && 2*7<=25;        flag[14]=false;    if(7%prime[0]==0) no
    j=1;j<4 && 3*7<=25;        flag[21]=false;    if(7%prime[1]==0) no
    j=2;j<4 && 5*7=35;break;
    
    i=8;i<=25;    no
    for
    j=0;j<4 && 2*8<=25;        flag[16]=false;    if(8%prime[0]==0) yes;break;
    
    i=9;i<=25;    no
    for
    j=0;j<4 && 2*9<=25;        flag[18]=false;    if(9%prime[0]==0) no;
    j=1;j<4 && 3*9=27;break;
    
    i=10;i<=25; no
    for
    j=0;j<4 && 2*10<=25;    flag[20]=false; if(10%prime[0]==0) yes;break;
    
    i=11;i<=25; yes;prime[4]=11;cnt=5
    for
    j=0;j<5 && 2*11<=25;    flag[22]=false;    if(11%prime[0]==0) no
    j=1;j<5 && 3*11=33;break;
    
    i=12;i<=25; no;
    for
    j=0;j<5 && 2*12<=25;    flag[24]=false;    if(12%prime[0]==0) yes;break;
    
    i=13;i<=25; yes;prime[5]=13;cnt=6
    for
    j=0;j<6 && 2*13=26 break;
    
    i=14;no
    for
    break;
    
    i=15;no
    for
    break;
    
    i=16;no
    for
    break;
    
    i=17; yesprime[6]=17;cnt=7
    for
    break;
    
    i=18;no
    for
    break;
    
    i=19; yes; prime[7]=19,cnt=8
    for
    break;
    
    i=20; no
    for
    break;
    
    i=21; no
    for
    break;
    
    i=22; no
    for
    break;
    
    i=23; yes; prime[8]=23;cnt=9
    for
    break;
    
    i=24;no
    for
    break;
    
    i=25;no
    for
    break;
    */
    
    
    
     
  • 相关阅读:
    java基础>I/O 小强斋
    动态查找>红黑树(RedBlack Tree) 小强斋
    java基础>I/O 小强斋
    动态查找>红黑树(RedBlack Tree) 小强斋
    1-N的自然数中,少了一个,找出这个数 小强斋
    oracle数据库导入导出 小强斋
    找出N个整数中最大的K个数 小强斋
    找出N个整数中最大的K个数 小强斋
    oracle数据库导入导出 小强斋
    2013长沙全国邀请赛总结
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/9483646.html
Copyright © 2020-2023  润新知