Eratosthenes筛法

来源:互联网 发布:复旦东区宿舍网络 编辑:程序博客网 时间:2024/06/16 01:29

如果要将素数建个表,我们可以从1~n每个数进行素数判断,如果是则放入数组里。这个效率不算很高,那么有一种算法可以更好实现——Eratosthenes筛法。它的思想就是:对于不超过n的每个非负整数p,删除2p,3p,4p,…,当处理完所有数之后,还没有被删除的就是素数。

#include<cstdio>#include<cstring>using namespace std;const int maxn = 10000000;int vis[maxn];void Eratosthenes(int n){    for(int i=2; i<=n; i++)    {        for(int j=2*i; j<=n; j+=i)        {            vis[j] = 1;        }    }    return;} int main(){    memset(vis,0,sizeof(vis));      int n;    scanf("%d",&n);    Eratosthenes(n);    for(int i=2; i<=n; i++)    {        if(!vis[i])        {            printf("%d ",i);        }    }    return 0;} 

优化一下:在“对于不超过n的每个非负整数p”中,p可以限定为素数——只需在第二重循环前加一个判断if(!vis[i])即可,另外,内层循环不需从i*2开始,因为它已经在i=2时被筛掉了。

#include<cstdio>#include<cstring>#include<cmath> using namespace std;const int maxn = 10000000;int vis[maxn];typedef long long L; void Eratosthenes(L n){    memset(vis,0,sizeof(vis));    L m = sqrt(n + 0.5);    for(L i=2; i<=m; i++)    {        if(!vis[i])        {            for(L j=i*i; j<=n; j+=i)            {                vis[j] = 1;            }        }     }    return;} int main(){    L n;    scanf("%lld",&n);    Eratosthenes(n);    for(L i=2; i<=n; i++)    {        if(!vis[i])        {            printf("%lld ",i);        }    }    return 0;}

那么紫书上引出的问题:
无平方因子的数: 给出正整数n和m,区间[n,m]内的“无平方因子”的数有多少个?
正整数p无平方因子,当且仅当不存在k > 1,使得p是k^2的倍数。

这个问题可以从n开始到m结束,然后一个个数去判断,这样明显爆炸。所以要采用筛素数的方式,从2到√m的素数p中,筛去区间[n.m]内p^2的所有倍数。

代码如下:

#include<cstdio>#include<cstring>#include<cmath> using namespace std;typedef long long LL;const LL maxn = 1000000000000;int vis[maxn], ans[maxn];LL n, m;int main(){    int n,m;    memset(vis,0,sizeof(vis));    int t=sqrt(maxn+0.5);    for(int i=2;i<=t;i++) if(!vis[i])        for(int j=i*i; j<=maxn; j+=i) vis[j]=1; //先筛素数     while(scanf("%d%d",&n,&m) == 2 && n && m)    {        int k = floor(sqrt(m+0.5));        memset(ans, 0, sizeof(ans));        for(int i=2; i<=k; i++)        if(!vis[i])        {                   int last = m / (i*i);            for(int crt=n/(i*i); crt<=last; crt++)            ans[(i*i)*crt]=1;        }//筛无平方因子数         int count=0;        for(int i=n; i<=m; i++)        {            if(!ans[i])            {                printf("%d ",i);                count++;            }        }        printf("\n");        printf("%d\n",count);    }       return 0;} 
0 0
原创粉丝点击