Acwing
题目描述
思路 1
思路一(最朴素做法):逐步筛去 每个数的倍数 的 数 ,这样晒过之后 ,剩下的为质数,比如11没有被删除,则说明1~10都不是11的约数,说以11的约数就只有1和他本身,因此11就是质数。
时间复杂度 O(n * logn)
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;//注意数据范围
int primes[N], cnt;
bool st[N];
void get_primes(int n) {
for (int i = 2; i <= n; i++) {
if(!st[i]) {
primes[cnt++] = i;
}
for (int j = i + i; j <= n; j += i) {
st[j] = true;
}
}
}
int main () {
int n;
cin >> n;
get_primes(n);
cout << cnt << endl;
return 0;
}
思路2:线性筛法 [用最小质因子去筛合数]
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int primes[N], cnt;
bool st[N];//质数则为false 否则为true
// 朴素做法
// void get_primes(int n) {
// for (int i = 2; i <= n; i++) {
// if(!st[i]) {//如果不是质数的话,就存起来
// primes[cnt++] = i;
// }
// for (int j = i + i; j <= n; j += i) {
// st[j] = true;//筛掉后面它的倍数
// }
// }
// }
void get_primes(int n) {
for (int i = 2; i <= n; i++) {
if(!st[i]) {
//如果是质数的话,就加入的质数表里面去
primes[cnt++] = i;
}
// primes[j] <= n / i == primes[j] * i <= n,而primes[j] * i就是所有要筛除的合数
for (int j = 0; primes[j] <= n / i; j ++) {
//枚举质数
st[primes[j] * i] = true;// 合数 = i * pj (pj为小于 i 的最小质因子
if(i % primes[j] == 0) {
break; //primes[j]一定是i的最小质因子
}//举个例子,对于一个数9,9*2=18将18标记为合数,循环继续;9*3=27将27标记为合数,
//此时发现9%3=0,循环退出。如果将循环继续下去会出现筛除9*5=45的情况,
//而45=15*3,在15时会被在筛去一次,故不可行
}
}
}
int main () {
int n;
cin >> n;
get_primes(n);
cout << cnt << endl;
return 0;
}