题解:学而思编程 质数

【题目来源】

学而思编程:质数

【题目描述】

质数是指在大于 \(1\) 的自然数中,除了 \(1\) 和它本身以外不再有其他因数的自然数。现在给定你两个整数 \(a,b\),请你找出 \(a\sim b\) 之间(不包含 \(a,b\))所有个位为 \(1\) 的质数。

【输入】

一行两个整数 \(a,b\)

【输出】

从小到大输出所有满足条件的质数,质数之间单个空格隔开,如果没有符合条件的质数输出 \(-1\)

【输入样例】

1 97

【输出样例】

11 31 41 61 71

【核心思想】

  1. 问题分析:给定区间 \((a, b)\),找出其中所有个位为 \(1\) 的质数。这是一个范围筛选 + 质数判定问题,关键在于利用个位约束减少待检查的数字数量,仅对个位为 \(1\) 的数进行质数判定。

  2. 算法选择

    • 个位筛选:只检查个位为 \(1\) 的数字,步长为 \(10\)
    • 试除法质数判定:对每个候选数,检查 \(2\)\(\sqrt{n}\) 是否有因数
    • 边界调整:将 \(a\) 向上调整到最近的 \(10\) 的倍数,确保从个位为 \(1\) 的数开始检查
  3. 关键步骤

    • 初始化:读取 \(a\)\(b\)

    • 边界调整

      • a % 10 != 0a = (a / 10 + 1) * 10:将 \(a\) 向上取整到最近的 \(10\) 的倍数
    • 筛选检查

      • flag = 0:标记是否找到符合条件的质数
      • 遍历 \(i\)a + 1b - 1,步长 \(10\)
        • isp(i) 为真:
          • 输出 \(i\)
          • flag = 1
    • 无解处理

      • flag == 0:输出 \(-1\)
    • 质数判定函数 isp(n)

      • n < 2:返回 false
      • 遍历 \(i\)\(2\)\(\sqrt{n}\)
        • n % i == 0:返回 false
      • 返回 true
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\frac{b-a}{10} \times \sqrt{b})\),仅检查约 \(\frac{b-a}{10}\) 个候选数
    • 空间复杂度:\(O(1)\),仅需常数变量
  5. 个位筛选的核心思想

    • 步长优化:个位为 \(1\) 的数间隔为 \(10\),用步长 \(10\) 遍历可将候选数减少 \(90\%\)
    • 边界对齐:将 \(a\) 调整到 \(10\) 的倍数后,a + 1 即为第一个个位为 \(1\) 的数,确保不遗漏
    • 开区间处理:循环条件 i < b 严格满足"不包含 \(b\)"的要求
    • 提前过滤:在质数判定前先用个位条件过滤,避免大量无效计算
    • 适用于"数位约束 + 质数筛选"类问题,利用数位规律大幅减少搜索空间

【算法标签】

质数

【代码详解】

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

int a, b;  // 输入的区间边界[a, b]
bool flag;  // 标记是否找到了符合条件的素数

// 判断一个数是否为素数
bool isp(int n)
{
    if (n < 2)  // 小于2的数不是素数
    {
        return false;
    }

    // 检查从2到√n的所有数
    for (int i = 2; i * i <= n; i++)
    {
        if (n % i == 0)  // 如果能被整除,不是素数
        {
            return false;
        }
    }

    return true;  // 是素数
}

int main()
{
    cin >> a >> b;  // 输入区间边界

    // 调整a为10的倍数(向上取整到最近的10的倍数)
    if (a % 10 != 0)
    {
        a = (a / 10 + 1) * 10;
    }

    // 在区间(a, b)内查找以1结尾的素数
    for (int i = a + 1; i < b; i += 10)
    {
        if (isp(i))  // 如果是素数
        {
            cout << i << " ";  // 输出这个素数
            flag = 1;  // 标记找到了素数
        }
    }

    // 如果没有找到符合条件的素数
    if (flag == 0)
    {
        cout << "-1";  // 输出-1
    }

    return 0;  // 程序正常结束
}

【运行结果】

1 97
11 31 41 61 71
posted @ 2026-07-05 15:53  团爸讲算法  阅读(4)  评论(0)    收藏  举报