题解:学而思编程 特殊素数对

【题目来源】

学而思编程:特殊素数对

【题目描述】

任意两个素数 \(a,b\) 满足 \(|a-b| = 6\) 我们称 \((a,b)\)特殊素数对\(a\)\(b\) 分别称为特殊素数,例如 \((5, 11), (7, 13), (11, 17), (13, 19), \ldots\) 都是特殊素数对,其中 \(5, 7, 11, 13, 19\) 分别都是特殊素数。现在给定一个整数 \(n\),请判断 \(n\) 是否是一个特殊素数。

【输入】

一行一个整数 \(n\)

【输出】

如果 \(n\) 是一个特殊素数,第一行输出 Yes,第二行输出与 \(n\) 配对的另一个特殊素数(如果这样的数不唯一,只需要输出较小的哪一个);

如果 \(n\) 不是一个特殊素数,第一行输出 No,第二行输出大于 \(n\) 的最小特殊素数。

【输入样例】

2

【输出样例】

No
5

【核心思想】

  1. 问题分析:给定整数 \(n\),判断是否为"特殊素数"(即存在另一个素数与其差为 \(6\))。若是,输出 Yes 和配对的较小素数;若否,输出 No 和大于 \(n\) 的最小特殊素数。这是一个素数判定 + 条件搜索问题,关键在于理解特殊素数的定义并进行双向验证。

  2. 算法选择

    • 素数判定:试除法判断一个数是否为素数
    • 双向配对检查:对于 \(n\),检查 \(n-6\)\(n+6\) 是否为素数
    • 递增搜索:若 \(n\) 不是特殊素数,从 \(n+1\) 开始逐个检查直到找到特殊素数
  3. 关键步骤

    • 素数判定函数 isPrime(n)
      • \(n \leq 1\):返回 false
      • 遍历 \(i\)\(2\)\(\sqrt{n}\):若 \(n \bmod i = 0\) 则返回 false
      • 否则返回 true
    • 主函数
      • 读取 \(n\)
      • 情况1:若 isPrime(n)isPrime(n-6)
        • 输出 Yesn-6(配对中较小的)
      • 情况2:否则若 isPrime(n)isPrime(n+6)
        • 输出 Yesn+6
      • 情况3:否则:
        • \(i = n+1\) 开始无限循环:
          • isPrime(i) 且 (isPrime(i+6)isPrime(i-6)):
            • 输出 No\(i\),跳出循环
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\sqrt{n})\) 素数判定,最坏情况搜索 \(O(V \times \sqrt{V})\)\(V\) 为值域)
    • 空间复杂度:\(O(1)\),仅需常数变量
  5. 双向验证的核心思想

    • 特殊素数对的定义\((a, b)\) 满足 \(|a-b| = 6\) 且均为素数,因此 \(n\) 是特殊素数当且仅当 \(n-6\)\(n+6\) 中至少有一个是素数
    • 配对选择:若 \(n-6\)\(n+6\) 均为素数,按题目要求输出较小的(即 \(n-6\)),因此先检查 \(n-6\)
    • 递增搜索保证:从 \(n+1\) 开始逐个检查,第一个满足条件的即为"大于 \(n\) 的最小特殊素数"
    • 素数判定复用isPrime 函数统一处理所有素数判定,代码简洁
    • 适用于"素数对判定 + 极值搜索"类问题,双向验证覆盖所有配对可能

【算法标签】

质数

【代码详解】

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

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

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

    return true;  // 是素数
}

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

    // 情况1:n是素数,且n-6也是素数
    if (isPrime(n) && isPrime(n - 6))
    {
        cout << "Yes" << endl << n - 6 << endl;  // 输出Yes和配对的素数
    }
    // 情况2:n是素数,且n+6也是素数
    else if (isPrime(n) && isPrime(n + 6))
    {
        cout << "Yes" << endl << n + 6 << endl;  // 输出Yes和配对的素数
    }
    // 情况3:n不是素数,或者没有距离6的素数对
    else
    {
        // 从n+1开始寻找第一个满足条件的素数
        for (int i = n + 1; ; i++)  // 无限循环,直到找到符合条件的素数
        {
            if (isPrime(i) && (isPrime(i + 6) || isPrime(i - 6)))  // 找到满足条件的素数
            {
                cout << "No" << endl << i << endl;  // 输出No和找到的素数
                break;  // 找到后退出循环
            }
        }
    }

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

【运行结果】

2
No
5
posted @ 2026-07-05 15:05  团爸讲算法  阅读(4)  评论(0)    收藏  举报