「一本通 6.2 练习 1」质因数分解

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

n 恰为两个不同质数之积,较小质因数必不超过 √n,从 2 试除到 ⌊√n⌋ 命中后用 n 除以它即得较大质数。

OJ: roj

题目 ID: 1620

难度:普及-

标签:数论枚举python

创建: 2026-09-30 22:30

更新: 2026-10-06 01:22

题目描述

给定正整数 n=p⋅qn = p \cdot q(p,qp, q 为不同质数),求 max⁡(p,q)\max(p, q)。

思路

两个质因数中小的那个必不超过 n\sqrt n(否则乘积超过 nn),从小到大试除 2∼⌊n⌋2 \sim \lfloor\sqrt n\rfloor,第一个整除 nn 的 dd 对应的商 n/dn/d 就是较大的质因数。

参考代码

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-30 22:30
# update_at: 2026-09-30 22:30

import sys
from math import isqrt


def solve() -> None:
    n = int(sys.stdin.buffer.read())

    # 设 n = p*q 且 p < q,则 p ≤ √n(否则 p*q > √n*√n = n 矛盾),
    # 所以最小质因子一定落在 [2, ⌊√n⌋] 内,从小到大试除到它即可。
    # 命中的第一个 d 必是质数:若 d 是合数,它的质因子更小、早就把 n 除尽了。
    p = next(d for d in range(2, isqrt(n) + 1) if n % d == 0)
    print(n // p)  # 商就是较大的那个质数


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-06 01:19
 * update_at: 2026-10-06 01:19
 */
#include <cstdio>

typedef long long ll;

ll n; // 输入的整数,是两个不同质数的乘积

// 试除找到较小的质因数,返回较大的那个质数
ll solve(ll x) {
    for (ll d = 2; d * d <= x; ++d) { // 较小质因数不超过 sqrt(x)
        if (x % d == 0) {
            return x / d; // d 是小质因数,x/d 是大质因数
        }
    }
    return x; // 兜底,理论上不会发生
}

int main() {
    scanf("%lld", &n);
    printf("%lld\n", solve(n));
    return 0;
}