试除法判素数
Primality Test by Trial Division
开始编码请实现 solution(n: int) -> bool,在 n 是素数时返回 True,否则返回 False。素数是指大于 1、且只有 1 和自身两个正因子的整数。按惯例,0 和 1 不是素数。
期望做法是**试除到 sqrt(n)**:对每个候选因子 d,从 2 到 floor(sqrt(n)),检查 d 是否整除 n;只要有一个能整除,n 就是合数。平方根上界源于:任何非平凡分解 n = a * b(a <= b)必然满足 a <= sqrt(n),所以只找较小的那个因子就够了。
干净的实现模板是:先把 n < 2、n = 2、n = 3、以及偶数 n 几种特例处理掉,再让奇数 d = 3, 5, 7, ... 在 d * d <= n 范围内迭代。
Examples
solution(2) 返回 True。最小的素数;n == 2 这个特例必须在偶数剪枝之前命中,否则会被错杀。
solution(9999991) 返回 True。是不超过 10⁷ 的最大素数。循环以 d = 3, 5, 7, ..., 3161 迭代(约 1581 个奇数候选,因为 3163² = 10004569 > 9999991),没有一个能整除 n,故返回 True。
solution(25) 返回 False。25 = 5 × 5,当 d = 5、d * d = 25 <= n 时,n % d == 0 触发,函数返回 False。这个例子说明为什么循环条件要写成 d * d <= n(不能是 <):素数的平方恰是平方根本身就是整数因子的输入。
签名见 stubs/stub.py。
Practical context
素性测试是公钥密码学的基础原语。RSA、Diffie-Hellman、DSA、椭圆曲线密钥生成都需要造出大素数(典型是 1024 或 2048 位),标准流水线是:先随机抽一个目标位长的奇整数,用试除法对前几千个小素数过一遍(这一步可以便宜地杀掉约 80% 的候选),然后跑 Miller-Rabin 概率测试,跑足够多的随机见证把假素数概率压到 2^-128 以下。试除到 sqrt(n)——也就是本题里的算法——是小素数筛预计算时的参考实现,同时也是 n 不超过约 10⁹ 时的确定性金标准(这个范围内 Miller-Rabin 配 {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37} 这套见证集已被证明完全正确)。本题里 sqrt 上界这条捷径——O(n) 和 O(sqrt(n)) 的差距——正是让 RSA 密钥生成可行的核心:1024 位下,朴素试除会比宇宙年龄还长,而「先小素数筛、后 Miller-Rabin」的结构化流水线只要几秒。除了密码学,素性测试还在哈希表选容量(用素数大小避免聚簇)、编码理论里的多项式模数选择(BCH、Reed-Solomon)、以及计算代数系统里的 Lehmer/AKS 算法中起作用。把这里的 d * d <= n 边界和奇数轮子吃透,就抓住了能放大到 4096 位 RSA 的同一套结构。
约束条件
- 0 ≤ n ≤ 10^7
- n 是非负整数
样例
Case 1 · typical: smallest prime
输入: [2]
期望: true
2 是最小的素数,也是唯一的偶素数。需要单独作为基准用例处理:偶数剪枝必须在 n=2 之后才生效。
Case 2 · typical: small odd prime
输入: [97]
期望: true
97 是 100 以内最大的素数。试除范围只到 sqrt(97) ≈ 9.85,依次试 3、5、7 都不能整除即可判断为素数。
Case 3 · typical: large prime near 10^7
输入: [9999991]
期望: true
9999991 是不超过 10^7 的最大素数。试除上界为 sqrt(9999991) ≈ 3162,需要遍历 ~1581 个奇数;O(sqrt(n)) 对 10^7 量级是 1ms 级,O(n) 则会跑 5×10^6 次循环。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · typical: smallest prime
输入: [2]
期望: true
2 是最小的素数,也是唯一的偶素数。需要单独作为基准用例处理:偶数剪枝必须在 n=2 之后才生效。
Case 2 · typical: small odd prime
输入: [97]
期望: true
97 是 100 以内最大的素数。试除范围只到 sqrt(97) ≈ 9.85,依次试 3、5、7 都不能整除即可判断为素数。
Case 3 · typical: large prime near 10^7
输入: [9999991]
期望: true
9999991 是不超过 10^7 的最大素数。试除上界为 sqrt(9999991) ≈ 3162,需要遍历 ~1581 个奇数;O(sqrt(n)) 对 10^7 量级是 1ms 级,O(n) 则会跑 5×10^6 次循环。