学习了一波欧拉筛 希望能记住模板进行应用
https://blog.csdn.net/qq_39763472/article/details/82428602
借鉴了这片博客 再加上一些自己的想法
#include <iostream>
using namespace std;
const int maxn=1e3;
int a[maxn],vis[maxn];
int main(){
//用a[0]储存质数的个数
for(int i=2;i<maxn;i++){
cout<<"i="<<i<<endl;
//如果未被标记过即为质数,将质数一个个存到数组里
if(!vis[i]) a[++a[0]]=i;
//枚举 遍历数组a[]里已经存在的每个质数 将这些质数的i倍标记
for(int j=1;j<=a[0]&&i*a[j]<=maxn;j++){
cout<<" j = "<<j<<" a["<<j<<"]"<<" = "<<a[j]<<" i*a[j] = "<<i*a[j]<<endl;
vis[i*a[j]]=1;
//精髓的一步
//一直往后枚举 当i%a[j]==0时 此时i是a[j]的倍数
//即 i=a[j]*k,如果继续枚举下去,当a[?]时 i*a[?]位置就被标记了
//即a[j]*k*a[?]这个位置被标记了,而之后i的for循环里 i=k*a[?]时
//这个位置还是会被重复标记
//而 i%a[j]==0 就break 确保了a[j]一定是i的最小质因子
if(i%a[j]==0) break;
}
}
return 0;
}
用图说话更清楚些:
这是把关键那句话注释之后的显示
可以看到 当i=4,a[2]=3时,此时vis[12]被标记了
而当 i=6,a[1]=2时,vis[12]又再次被标记
加了精华之后 就舒服了
只有 当i=6时 vis[12]会被标记
这是别的都删去了的代码 还挺美的
#include <iostream>
using namespace std;
const int maxn=1e3;
int a[maxn],vis[maxn];
int main(){
for(int i=2;i<maxn;i++){
cout<<"i="<<i<<endl;
if(!vis[i]) a[++a[0]]=i;
for(int j=1;j<=a[0]&&i*a[j]<=maxn;j++){
vis[i*a[j]]=1;
if(i%a[j]==0) break;
}
}
return 0;
}