










http://ybt.ssoier.cn:8088/problem_show.php?pid=1151
编程求2∼n中有多少个素数。
用线性筛
线性筛的核心思想:
关键规则:
i 从 2 到 ni 未被标记,是素数 → 加入素数表p:
i * p 为合数p 是 i 的最小质因子(i % p == 0),就停止继续乘更大的质数(确保线性复杂度)#include <bits/stdc++.h>
using namespace std;
// 线性筛模板:统计 2~n 的素数个数
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> primes; // 存放所有素数
vector<bool> is_composite(n+1, false); // 标记合数
// 欧拉线性筛
for (int i = 2; i <= n; i++) {
// 若 i 未被标记,则为素数
if (!is_composite[i]) {
primes.push_back(i);
}
// 用当前所有已知素数筛掉 i*p
for (int p : primes) {
// 超界则退出
if (1LL * i * p > n) break;
is_composite[i * p] = true; // 标记为合数
// 若 p 是 i 的最小质因子,则停止继续
// 保证每个合数只被处理一次(线性复杂度核心)
if (i % p == 0) break;
}
}
// 输出素数个数
cout << primes.size() << "\n";
return 0;
}
如果你需要版本:输出所有素数 / 多次询问 / 给出素数表上界优化,也可以继续问我!
下面这个代码错在哪里?
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+100;
bool visit[N];
int prime[N],n,x,cnt1;
void init(int n){
int cnt=0;
for(int i=2;i<=n;i++){
if(!visit[i]) prime[cnt++]=i;
for(int j=0;j<cnt;j++){
if(i*prime[j]>n) break;
visit[i*prime[j]]=1;
cnt1++;
if(i%prime[j]==0) break;
}
}
}
int main(){
cin>>n;
init(n);
cout<<cnt1-1;
return 0;
}
下面指出你代码中的 核心错误与原因,并给出 正确写法。
cnt1-1,但 cnt1 根本不是素数个数你把 cnt1 写成:
cnt1++;
它是在 每次筛掉一个数时 +1
也就是「筛选操作次数」,不是「素数数量」!
所以:
cnt1 ≠ 素数数量cnt1 - 1 更是完全没有意义因此逻辑错误,输出错。
cnt 是局部变量你写了:
int prime[N], n, x, cnt1;
void init(int n){
int cnt = 0; // <-- 局部变量!
问题:
cnt 在 init() 内是局部的main() 里无法获取到素数数量prime[] 也没有全局保存素数个数信息所以程序最终无法得知 prime 里存了多少素数。
而不是筛掉多少个数。
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 100;
bool vis[N];
int prime[N], n, cnt = 0; // cnt 全局,表示素数个数
void init(int n) {
for (int i = 2; i <= n; i++) {
if (!vis[i]) prime[cnt++] = i; // 记录素数
for (int j = 0; j < cnt; j++) {
if (1LL * i * prime[j] > n) break;
vis[i * prime[j]] = true;
if (i % prime[j] == 0) break; // 关键剪枝
}
}
}
int main() {
cin >> n;
init(n);
cout << cnt << "\n"; // 输出素数个数
return 0;
}
| 错误 | 原因 |
|---|---|
cnt1 统计的是筛掉次数 |
不是素数个数,输出错 |
素数计数 cnt 写在函数内部 |
main 拿不到,逻辑错误 |
最终输出 cnt1-1 |
完全不正确 |
正确做法:用全局 cnt 来统计素数数量并输出。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。