这也是一个易超时题,下面来讲讲解题算法
首先还是上题目:
总时间限制: 5000ms 内存限制: 65536kB
描述
一个数如果从左往右读和从右往左读数字是相同的,则称这个数是回文数,如121,1221,15651都是回文数。给定位数n,找出所有既是回文数又是素数的n位十进制数。(注:不考虑超过整型数范围的情况)。
输入
位数n,其中1<=n<=9。
输出
第一行输出满足条件的素数个数。
第二行按照从小到大的顺序输出所有满足条件的素数,两个数之间用一个空格区分。
样例输入
1
样例输出
4
2 3 5 7
一读完题目,我们运用常规蛮力的思想很容易就会想到根据输入的n去找一类数它既满足素数又满足回文数。
如果你就是这么想的的话,所以你就找到这里来了。
百度搜索回文素数会发现,任何回文素数都不是偶次位除了2(有一个回文素数11)
这就在间接地提醒我们对于奇数位与偶数位可以分开处理,并且偶数位可以不处理,直接输出0;
我在我的电脑里面验证多次,发现每次输入9时电脑大概要跑45s,而这个时间已经大大超出题目的范围了。
那么这些时间主要是花在哪些地方了呢?
首先是第一个循环遍历的范围很广,如果输入9,就要从100000000至999999999,然后再验证是否为素数和是否为回文数,显然,先判断是否为回文数效率会高很多,因为素数的判别即使采用平方数为终点仍然是个非常耗时的算法。但是经过验证还是过不了。
判断回文数的步骤说不上多复杂,而判断素数的算法也已经优化到了接近极限,唯一的突破口就在于对于第一层循环的遍历范围能不能进行缩小?(当输入9,需要遍历910^8次)
所以就有了下面的算法:
第一步,构造回文数,这一步骤并不是对以往判别回文数的优化,而是为了大大减小遍历的范围(当输入9,需要遍历910^5次)
显然,优化量是非常巨大的!
第二步,判断构造的回文数是否为素数。
下面是ac的c++代码:
#include<iostream>
using namespace std;
int nn