核心思想:最小质因数(prime[j])×最大因数(i)=一个合数 并保证每个合数只筛查一遍
因为若i为合数,则最小质因数(prime[j])和最大因数(i)一定在i-1之内,而经过筛选后没有筛掉i
,那么i就是素数
if (a[i] != 1)
{
prime[num] = i;
num++;
}
if (i % prime[j] == 0) break; //余数为0说明prime[j]为i的最小质因数,由于
余数为0说明prime[j]为i的最小质因数,(因为prime中质数由小到大排列)
这一步就保证了不会重筛,堪称神来之笔!
#include <stdio.h>
int n; //范围
int a[100000003] ; //筛素数 初始化都为0,赋值1则不是素数
int prime[10000000];//存素数
int num;//记录素数个数
void isprime();
int main() {
scanf("%d", &n);
isprime();
for (int i = 0; i <num; i++) {
printf("%d", prime[i]);
}
return 0;
}
void isprime() {
for (int i = 2; i <=n; i++) { //i<n 不能把写为i<=sqrt(n),由于每次for循环是将i筛出来,那么必须筛到n
if (a[i] != 1)
{
prime[num] = i;
num++;
}
for (int j = 0; j < num&& prime[j] * i <= n; j++) {
a[prime[j] * i] = 1; //将合数=最小质因数×最大因数 筛出
if (i % prime[j] == 0) break; //余数为0说明prime[j]为i的最小质因数,由于
}
}
}