质因数分解

GitHub跳转原题关系图返回列表

n 是两个不同质数之积,从小到大试除到 sqrt(n) 找最小质因子 p,输出 n/p 即较大质数,O(sqrt(n))。

OJ: roj

题目 ID: 1098

难度:入门

标签:入门数学python

创建: 2026-09-29 18:39

更新: 2026-10-05 01:00

题目描述

已知正整数 nn 是两个不同质数的乘积(6≤n≤2×1096 \le n \le 2 \times 10^9),求较大的那个质数。输入一行一个 nn,输出一行较大的质数。样例输入 21,输出 7(21=3×721 = 3 \times 7)。

思路

设 n=p⋅qn = p \cdot q 且 p<qp < q,则必有 p<np < \sqrt{n}:否则 p,qp, q 都大于 n\sqrt{n},乘积会超过 nn。于是从小到大枚举 d=2,3,…,⌊n⌋d = 2, 3, \dots, \lfloor\sqrt{n}\rfloor,第一个整除 nn 的 dd 就是较小的质数 pp(若 dd 是合数,它必有更小的因子也整除 nn,与“第一个”矛盾),输出 n/pn / p 即可,复杂度 O(n)O(\sqrt{n})。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-09-29 18:39
# update_at: 2026-09-29 18:39

import sys


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    n = next(data)

    # 两个不同质数相乘,较小的那个必定 ≤ sqrt(n),
    # 从小到大试除,找到的第一个因子就是较小质数。
    p = next(d for d in range(2, int(n**0.5) + 1) if n % d == 0)

    print(n // p)  # 较大质数 = n / 较小质数


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-05 00:59
 * update_at: 2026-10-05 00:59
 */
// main.cpp:试除法求较大的质因子。
// n = p*q 且 p<q 为两个不同质数,从小到大第一个整除 n 的 d 就是 p,答案 n/p。
#include <iostream>

typedef long long ll;

int main() {
    ll n;
    std::cin >> n;

    // p < sqrt(n) < q,枚举到 sqrt(n) 即可;找到的第一个因子必为较小质数 p。
    for (ll d = 2; d * d <= n; d++) {
        if (n % d == 0) {
            std::cout << n / d << std::endl;
            return 0;
        }
    }

    // 理论上 n 至少含两个不同质因子,不会走到这里。
    std::cout << 1 << std::endl;
    return 0;
}