在C++中,筛素数是一个非常重要算法。
我花了半天时间才明白的欧拉筛(我实在是太蒻了)。
最愚蠢的方法:
1 #include<cstdio> 2 int main(){ 3 int n,k; 4 scanf("%d",&n); 5 for(int i=1;i<=n;i++){ 6 if(n%i==0){ 7 printf("yes"); 8 return 0; 9 } 10 } 11 printf("no"); 12 }
普通方法:
1 #include<cstdio> 2 int main(){ 3 int n,k; 4 scanf("%d",&n); 5 for(int i=1;i<=sqrt(n);i++){ 6 if(n%i==0){ 7 printf("yes"); 8 return 0; 9 } 10 } 11 printf("no"); 12 }
以上两种方法其实都是判定方法,并不是筛法,下面说真正的筛法:
1.埃筛法:
1 #include<iostream> 2 using namespace std; 3 int main(){ 4 int i,j,n,flag=1; 5 bool a[100]={0}; 6 for(i=1;i<=100;i++){ 7 for(j=2;j<=100;j++){ 8 a[i*j]=1; 9 } 10 } 11 for(int p=0;p<=100;p++) 12 if(a[p]==0){ 13 cout<<a[p]<<" "; 14 } 15 return 0; 16 }
思路:首先将所有2的倍数标为1,再将所有3的倍数标为1……以此类推。
2.欧拉筛:
1 #define MAXN 1000000 2 int main(){ 3 int chk[MAXN]={0}; 4 int p[MAXN]={0}; 5 int t=0; 6 for (int i=2;i<MAXN;i++){ 7 if (!chk[i]) 8 p[t++]=i; 9 for (int j=0;j<t&& i*p[j]<MAXN;j++) 10 { 11 chk[i*p[j]] = 1; 12 if (i%p[j]==0) 13 break; 14 } 15 } 16 }
思路:由于埃筛法做了许多不必要的循环,所以欧拉筛在埃筛法的基础上,省去了一些步骤,时间复杂度O(n)。