<题目描述>
求出大于或等于 N 的最小回文素数。
回顾一下,如果一个数大于 1,且其因数只有 1 和它自身,那么这个数是素数;如果一个数从左往右读与从右往左读是一样的,那么这个数是回文数。
<原题链接>
https://leetcode-cn.com/problems/prime-palindrome
<理明思路>
简言之就是即是回文又是质数。我们可以将其分成两部分来判断:1.是回文 2.是质数
在初识c语言的时候我们曾分别码过关于判断质数和回文的算法。在此只需将其“有机”地结合起来即可。下面是样例代码,依旧使用的是令人非常容易想到的遍历。在完成代码之前,这一次我们不得不考虑时间复杂度的问题了,随着数值的增大,计算所消耗的时间也会越来越长,而且每当数值N扩大十倍,运算时间都可能会爆炸增长。那么怎样在这种情况下节省时间是个很重要的方法。
- 在这里给出一段与下面代码所配套使用的main函数,可以计算并列出所有题目要求内的回文素数。
int main(int argc, char const *argv[])
{
Solution slu;
int x, y=0;
for(int a=3;a<SUPER_NUMBER;a+=2)
{
x=slu.primePalindrome(a);
if(x!=y)
{
cout<<x<<endl;
y=x;
}
}
return 0;
}
使用C++编码多少还是有点生疏。。。
<样例代码>
#include<iostream>
#include<vector>
#define SUPER_NUMBER 9989900
using namespace std;
class Solution {
public:
bool is_prime(int x);
bool is_palindromic(int num);
int primePalindrome(int N) {
if(N<1||N>1e+8)
{
/*cout<<__LINE__<<endl;*/
exit(1);
} //判断数值是否不符
switch(N){
case 1:return 2;
case 2:return N;
}
if(N>=SUPER_NUMBER) //大于该数字而且小于1e8的回文只有这一个(通过计算得来)。
return 100030001;
if(N!=2&&N%2==0) N++;
for(int i=0;i<N;i+=2) //不要逐个历遍。
{
if(is_palindromic(N))
if(is_prime(N)) //如果是质数而且是回文。
return N;
N+=2;
}
exit(0);
}
};
bool Solution::is_prime(int x)
{
//来到这里的x一定大于2且是一个奇数回文。
for(int i = 2;i<x;i++)
{
if(x%i==0)
{/*cout<<__LINE__<<endl;*/return false;}
}
return true;
}
bool Solution::is_palindromic(int num)
{
vector<int> vct;
vector<int>::iterator vbi;
vector<int>::iterator vei;
int j=1,data;
while((num/j)!=0)
j*=10;
j/=10; //知道了num是几位数。
if(j==1) return true; //如果个位数直接返回。
while(j!=0)
{
vct.push_back(num/j);
data=j;data*=(num/j);num-=data; //去除最高位。
j/=10;
}
vei = vct.end()-1;
for(vbi = vct.begin(); vbi < vei; vbi++,vei--) //不可以用vbi!=vci;
{
if(*vbi!=*vei)
{/*cout<<__LINE__<<endl;*/return false;}
}
return true;
}
//省略main函数