简易筛质数
一、int is(int n) 的作用是什么?
1 | int is(int n) |
👉 作用:判断一个整数 n 是否是质数(素数)
- 返回
1:n是质数 - 返回
0:n不是质数
所以它本质上是一个 质数判定函数。
二、为什么这样写能判断质数?
1️⃣ 质数的定义
质数:只能被
1和自身整除的正整数(n ≥ 2)
2️⃣ 为什么从 i = 2 开始?
1肯定能整除任何数,没意义- 所以从 最小可能的因子
2开始试
3️⃣ 为什么只枚举到 i * i <= n?
这是关键点 👇
数学原理:
如果 n 是合数:
1 | n = a × b |
那么:
- 至少有一个因子 ≤ √n
- 如果两个因子都 > √n,那么乘积会 > n(矛盾)
✅ 所以:
只要检查到 √n,就能确定 n 是否有因子
这也是为什么不用枚举到 n-1,可以大幅优化速度。
4️⃣ if(n % i == 0) return 0;
- 找到一个能整除
n的数 - 说明
n不是质数 - 立刻返回
0(提前结束,节省时间)
5️⃣ return 1;
- 循环结束都没找到因子
- 说明
n是质数
三、它在 solve() 里起什么作用?
1 | for(int i=2;i<=10000;i++) |
👉 这段代码的作用是:
- 筛出 2 ~ 10000 之间的所有质数
- 存进
vector<int> a
后面这一步:
1 | pow(a[i],2) + pow(a[j],3) + pow(a[k],4) |
说明题目要求的是:
质数² + 质数³ + 质数⁴
所以必须先把 质数集合 算出来,is() 就是为这个服务的。
四、为什么不用更简单的方法?
你可能会想到:
1 | for(int i=2;i<n;i++) |
❌ 这样是 O(n)
现在这种写法是 O(√n),速度快很多。
在竞赛中:
n ≤ 10000- 判 10000 次质数
- 这种写法完全没问题
五、这个函数有没有问题?(重要)
❌ 潜在 bug
1 | is(1) 会返回 1(错误) |
因为循环不进,直接 return 1
✅ 更严谨写法:
1 | bool isPrime(int n) |
六、一句话总结(你记这个就够)
is(int n)用来判断 n 是否是质数,通过枚举 2 到 √n 的因子,高效且常见,是竞赛中最基础的质数判定方法。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 zhaijiang的小窝!

