题解:学而思编程 特殊素数对
【题目来源】
学而思编程:特殊素数对
【题目描述】
任意两个素数 \(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
【核心思想】
-
问题分析:给定整数 \(n\),判断是否为"特殊素数"(即存在另一个素数与其差为 \(6\))。若是,输出
Yes和配对的较小素数;若否,输出No和大于 \(n\) 的最小特殊素数。这是一个素数判定 + 条件搜索问题,关键在于理解特殊素数的定义并进行双向验证。 -
算法选择:
- 素数判定:试除法判断一个数是否为素数
- 双向配对检查:对于 \(n\),检查 \(n-6\) 和 \(n+6\) 是否为素数
- 递增搜索:若 \(n\) 不是特殊素数,从 \(n+1\) 开始逐个检查直到找到特殊素数
-
关键步骤:
- 素数判定函数
isPrime(n):- 若 \(n \leq 1\):返回
false - 遍历 \(i\) 从 \(2\) 到 \(\sqrt{n}\):若 \(n \bmod i = 0\) 则返回
false - 否则返回
true
- 若 \(n \leq 1\):返回
- 主函数:
- 读取 \(n\)
- 情况1:若
isPrime(n)且isPrime(n-6):- 输出
Yes和n-6(配对中较小的)
- 输出
- 情况2:否则若
isPrime(n)且isPrime(n+6):- 输出
Yes和n+6
- 输出
- 情况3:否则:
- 从 \(i = n+1\) 开始无限循环:
- 若
isPrime(i)且 (isPrime(i+6)或isPrime(i-6)):- 输出
No和 \(i\),跳出循环
- 输出
- 若
- 从 \(i = n+1\) 开始无限循环:
- 素数判定函数
-
时间/空间复杂度:
- 时间复杂度:\(O(\sqrt{n})\) 素数判定,最坏情况搜索 \(O(V \times \sqrt{V})\)(\(V\) 为值域)
- 空间复杂度:\(O(1)\),仅需常数变量
-
双向验证的核心思想:
- 特殊素数对的定义:\((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
浙公网安备 33010602011771号