题解:洛谷 P10720 小杨的幸运数字

【题目来源】

洛谷:P10720 [GESP202406 五级] 小杨的幸运数字 - 洛谷

【题目描述】

小杨认为他的幸运数字应该恰好有两种不同的质因子,例如,\(12=2×2×3\) 的质因子有 \(2,3\),恰好为两种不同的质因子,因此 \(12\) 是幸运数字,而 \(30\) 的质因子有 \(2,3,5\),不符合要求,不为幸运数字。

小杨现在有 \(n\) 个正整数,他想知道每个正整数是否是他的幸运数字。

【输入】

第一行包含一个正整数\(n\) ,代表正整数个数。

之后 \(n\) 行,每行一个正整数。

【输出】

输出 \(n\) 行,对于每个正整数,如果是幸运数字,输出 \(1\) ,否则输出 \(0\)

【输入样例】

3
7
12
30

【输出样例】

0
1
0

【核心思想】

  1. 问题分析:给定 \(n\) 个正整数,判断每个数是否恰好有两个不同的质因子。这是一个质因数分解 + 集合去重问题,核心在于对每个数进行质因数分解并统计不同质因子的个数。

  2. 算法选择

    • 试除法分解质因数:从 \(2\)\(\sqrt{x}\) 枚举因子,分解并记录不同质因子
    • 集合去重:使用 set 自动去重,统计不同质因子的数量
  3. 关键步骤

    • 读入数据:读取 \(n\)
    • 逐数判定(对每个数 \(num\)):
      • \(calc(num)\):分解质因数
        • 枚举 \(i\)\(2\)\(\sqrt{x}\)
          • \(x \bmod i = 0\):将 \(i\) 插入集合,然后不断除以 \(i\) 直到不能整除
        • \(x > 1\):将剩余的 \(x\) 插入集合(大质因子)
        • 返回集合大小
      • \(calc(num) = 2\):输出 1
      • 否则:输出 0
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n \cdot \sqrt{V})\),其中 \(V\) 为输入数的最大值
    • 空间复杂度:\(O(\log V)\),存储质因子的集合
  5. 质因数分解与集合去重的核心思想

    • 试除法的效率:只需枚举到 \(\sqrt{x}\),若 \(x\) 有大于 \(\sqrt{x}\) 的质因子,则最多只有一个,最后单独判断
    • 集合自动去重set 容器自动处理重复质因子(如 \(12 = 2^2 \times 3\)\(2\) 只计一次),无需手动判断
    • 完全分解的必要性:遇到因子 \(i\) 时必须将所有 \(i\) 的幂次除尽,避免将同一质因子重复计入
    • 边界情况:质数(如 \(7\))只有一个质因子,输出 \(0\)\(1\) 没有质因子,输出 \(0\);恰好两个不同质因子的数(如 \(12 = 2^2 \times 3\))输出 \(1\)
    • 适用于基础数论分解、质因子统计类入门问题

【算法标签】

普及- #约数

【代码详解】

#include <bits/stdc++.h>
using namespace std;

// 计算一个数的不同质因数个数
int calc(int x) {
    set<int> prime_factors;  // 使用集合存储不同的质因数

    // 分解质因数
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0) {
            prime_factors.insert(i);  // 插入质因数
            while (x % i == 0) {
                x /= i;  // 除去所有该因数
            }
        }
    }

    // 处理剩余的大于1的质因数
    if (x > 1) {
        prime_factors.insert(x);
    }

    return prime_factors.size();  // 返回不同质因数的个数
}

int main() {
    int n;
    cin >> n;  // 输入数字个数

    for (int i = 1; i <= n; i++) {
        int num;
        cin >> num;  // 输入每个数字

        // 计算并判断质因数个数是否为2
        if (calc(num) == 2) {
            cout << "1\n";  // 恰好两个不同质因数
        } else {
            cout << "0\n";  // 其他情况
        }
    }

    return 0;
}

【运行结果】

3
7
0
12
1
30
0
posted @ 2026-07-17 15:19  团爸讲算法  阅读(4)  评论(0)    收藏  举报