在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)。
