//本题思路并不难想,如果区间内的数既是素数,也是回文数,那么就是回文素数,写两个函数判断素数和回文数即可。然鹅本题并不会让你那么轻松通过(毕竟难度是普及-呢),很有可能你过了样例,但是提交得到的结果是一片RE(超时),因为本题最大数据达到了一亿,一个个的遍历,必然会很浪费时间,所以需要一定的优化,把部分数据直接排除。具体优化如下:
1:偶数必然不是素数,所以偶数不用考虑;
2:由数论知识得:偶数位的回文数,除了11其他的都可以被11整除,必然不是素数,所以最大数据只需到10000000(一千万,10000000~100000000之间的数都是八位数,偶数,可直排除) (详见https://www.zhihu.com/question/67646272)
3:用埃拉托色尼法筛选素数,节省时间(详见https://blog.csdn.net/qq_45472866/article/details/104051475)
下面是我AC的代码:
#include<stdio.h>
void checkprime(int p);
int prime[10000000]; //只需开到一千万(开到一亿的话,会超内存)
int is_huiwen(int p);
int main() {
int a, b, left, right, i; //left为区间左端点,right为右端点
scanf("%d%d", &a, &b);
if (a % 2 == 0) //把左端点初始化为奇数
left = a + 1;
else
left = a;
if (b > 10000000) //右端点最大只需一千万
b = 10000000;
right = b;
checkprime(right); //筛法求1~n之间的素数
for (i = left; i <= right; i += 2) { //由于只对奇数操作,故每次加2
if (prime[i] && is_huiwen(i)) //如果一个数既是素数也是回文数
printf("%d\n", i); //输出这个数
}
return 0;
}
int is_huiwen(int p) {
int ans, temp;
temp = p; //拷贝p,对temp操作
ans = 0;
while (temp) { //得到p的每一位
ans = ans * 10 + temp % 10; //把p的低位作为ans的高位
temp /= 10;
}
if(ans == p) //最终得到的ans和p位相反(例如p = 1234, 则ans = 4321),如果p和ans相等,那么p就是回文数
return 1;
return 0;
}
void checkprime(int p) {
int i;
for (i = 2; i <= p; i++)
prime[i] = 1;
for (i = 2; i * i <= p; i++){
if (prime[i])
for (int j = i; j * i <= p; j++)
prime[j * i] = 0;
}
}
来源:CSDN
作者:呆码农梦中识bug,程序员哭求加工资
链接:https://blog.csdn.net/qq_45472866/article/details/104104425