洛谷-P3912素数个数题解
P3912 素数个数
题目描述
求 1 , 2 , ⋯ , N 1,2,\cdots,N 1,2,⋯,N 中素数的个数。
输入格式
一行一个整数 N N N。
输出格式
一行一个整数,表示素数的个数。
输入输出样例 #1
输入 #1
10
输出 #1
4
说明/提示
对于 40 % 40\% 40% 的数据, 1 ≤ N ≤ 10 6 1 \le N \le 10^6 1≤N≤106。
对于 80 % 80\% 80% 的数据, 1 ≤ N ≤ 10 7 1 \le N \le 10^7 1≤N≤107。
对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 10 8 1 \le N \le 10^8 1≤N≤108。
看题目,如果我们没有学过埃氏筛法的话,你一定会这样写:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int N, ans;
bool prime(int t){if(t < 1) return false;for(int i = 2; i < t; i ++){if(t % i == 0) return false;}return true;
}
signed main(){cin >> N;for(int i = 2; i <= N; i ++){if(prime(i)) ans ++;}cout << ans;return 0;
}
对吧,从 1 1 1 一直搞到 N N N,看看哪些是素数,然后就让累加器统计一下,但是呢:
惨不忍睹啊,只拿了20分;
让我们重新看题目,他既然是统计 1 1 1 到 N N N 之间的素数个数的话,必须要使用埃氏筛法(没学过的点这里)
好,重新编写代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e8 + 7;
int n, a[N], ans;
void solve(){//听说可以减时间复杂度 cin >> n;a[1] = 1;//1不是质数,标记1 for(int i = 2; i * i <= n; i ++){//开方减复杂度 if(a[i] == 0){//是质数 for(int j = i * 2; j <= n; j += i){//倍数都不是质数 a[j] = 1;//标记 }}}for(int i = 1; i <= n; i ++){if(a[i] == 0) ans ++;//统计 }cout << ans;
}
signed main(){solve();return 0;
}
结果:
我真是可悲~~~~(>_<)~~~~
无语了。
发现了:long long
数组不可以开 10 8 10^8 108 这么大,可以改成bool
类型:
真是太难了,修改了 2 2 2 遍才改好:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e8 + 7;
int n, ans;
bool a[N];
void solve(){//听说可以减时间复杂度 cin >> n;a[1] = 1;//1不是质数,标记1 for(int i = 2; i * i <= n; i ++){//开方减复杂度 if(a[i] == 0){//是质数 for(int j = i * 2; j <= n; j += i){//倍数都不是质数 a[j] = 1;//标记 }}}for(int i = 1; i <= n; i ++){if(a[i] == 0) ans ++;//统计 }cout << ans;
}
signed main(){solve();return 0;
}