对称素数 = 既是素数(只能被 1 和自身整除的大于 1 的整数),又是回文数(正读和反读都相同的数,如 131、151)。
实现思路
把问题拆分为两个核心子功能,再组合判断:
- 判断素数:排除小于 2 的数,遍历 2 到√n,判断是否能被整除;
- 判断回文数:将数字反转,比较反转后的数是否等于原数;
- 组合判断:只有同时满足 "素数" 和 "回文数",才是对称素数。
cpp
#include <stdio.h>
#include <math.h>
#define _CRT_SECURE_NO_WARNINGS 1
// 判断是否为素数
bool isPrime(int n) {
//小于2的数不是素数
if (n < 2) {
return false;
}
int i = 2;
// 只需遍历到√n(减少循环次数)
for (i=2; i * i <= n; i++) {
// 能被整除,不是素数
if (n % i == 0) {
return false;
}
}
return true;
}
// 判断是否为回文数(对称数)
bool isPalindrome(int n) {
// 负数不是回文数(对称素数只考虑正整数)
if (n < 0) {
return false;
}
int original = n; // 保存原数
int reversed = 0; // 存储反转后的数
// 反转数字
while (n > 0) {
// 取最低位拼到反转数中
reversed = reversed * 10 + n % 10;
// 丢弃最低位
n = n / 10;
}
// 反转后等于原数,就是回文数
return reversed == original;
}
// 判断是否为对称素数
bool isSymmetricPrime(int n) {
// 必须同时满足:是素数 + 是回文数
return isPrime(n) && isPalindrome(n);
}
int main()
{
// 输出 5 位以内的全部对称素数
for (int i = 2; i < 9999; ++i) {
int res = isSymmetricPrime(i);
if(res)
printf("%d\n",i);
}
return 0;
}