is_strong_prime需先判断p是否为素数,再根据题目定义验证:最常见定义是p > (prev_prime + next_prime) / 2,即2*p > prev_prime + next_prime;需处理边界(如p=2无前驱)、溢出(用long long)及高效查找邻素数(预筛或优化试除)。

美利坚强素数(Strong Prime)不是 C++ 语言内置概念,也不是标准数学定义中的通用术语——它实际是某些 OJ 题或教学题中自定义的判定逻辑,常见定义为:一个素数 p,满足 p > (prev_prime + next_prime) / 2,即严格大于其前后相邻两个素数的平均值。
怎么写 is_strong_prime?先确认你用的是哪个定义
不同题目对“强素数”定义可能不同。最常见的是基于邻近素数的不等式判断,但也有题目定义为:p 是素数,且 (p - 1) 有大素因子、(p + 1) 有大素因子(密码学意义),或要求 p 比前一个素数至少大 2、比后一个至少小 2(gap-based)。务必以题目描述为准,别默认套用维基百科的密码学定义。
实操建议:
- 打开题目原文,逐字读清对
strong_prime的数学描述,重点关注是否提到prev_prime、next_prime、(p-1)、(p+1)或gap - 若题目没给定义,按竞赛常见惯例:先写
is_prime,再找上下两个最近素数,最后判断p * 2 > prev_prime + next_prime(避免浮点除法) - 注意边界:最小素数 2 没有前一个素数,通常直接返回
false;3 的前一个是 2,后一个是 5,计算得3*2=6 > 2+5=7?不成立 → 3 不是 strong prime
如何高效找 prev_prime 和 next_prime?别暴力试除到 p
对每个待测 p,如果每次都从 p-1 往下试除找前一个素数、从 p+1 往上试除找后一个,最坏情况时间爆炸(比如测一个大 p 附近素数稀疏时)。应复用已有素数表或优化搜索范围。
实操建议:
- 若测试范围固定(如
1e6内),预处理欧拉筛得到所有素数,存入vector<int> primes</int>,然后用lower_bound找位置,primes[i-1]和primes[i+1]就是邻项 - 若范围大或动态查询,
prev_prime只需从p-1向下检查,但可跳过偶数(除 2 外);next_prime同理,且一旦找到就立刻停 —— 不用算全量 - 注意:
is_prime函数本身要高效。对int范围内数,试除到sqrt(n)即可;若用 6k±1 优化,记得特判 2 和 3
常见错误:整数溢出和边界漏判
写 p * 2 > prev_prime + next_prime 看似简单,但 prev_prime + next_prime 可能溢出 int(尤其当 p 接近 INT_MAX 时)。另外,很多代码忘记处理 p == 2 或 p == 3 这类小值。
实操建议:
- 用
long long做中间运算:(long long)prev_prime + next_prime,再跟(long long)p * 2比较 - 明确返回
false的情形:非素数、p == 2(无前驱)、p是最大已知素数(无后继,除非你保证输入在表内) - 测试用例至少覆盖:
2、3、5(前2后7 →5*2=10 > 2+7=9→ true)、7(前5后11 →14 > 16?false)
真正麻烦的不是逻辑,而是题目没说清定义、或者测试数据包含极大素数导致超时。动手前,先 grep 题目描述里的“strong prime”原文,再决定用筛法还是单点判定。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











