# [USACO1.5]回文质数 Prime Palindromes
## 题目描述
因为 $151$ 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 $151$ 是回文质数。
写一个程序来找出范围 $[a,b] (5 \le a < b \le 100,000,000)$(一亿)间的所有回文质数。
## 输入格式
第一行输入两个正整数 $a$ 和 $b$。
## 输出格式
输出一个回文质数的列表,一行一个。
## 样例 #1
### 样例输入 #1
```
5 500
```
### 样例输出 #1
```
5
7
11
101
131
151
181
191
313
353
373
383
```
## 提示
Hint 1: Generate the palindromes and see if they are prime.
提示 1: 找出所有的回文数再判断它们是不是质数(素数).
Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.
提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。
题目翻译来自NOCOW。
USACO Training Section 1.5
产生长度为 $5$ 的回文数:
```cpp
for (d1 = 1; d1 <= 9; d1+=2) { // 只有奇数才会是素数
for (d2 = 0; d2 <= 9; d2++) {
for (d3 = 0; d3 <= 9; d3++) {
palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
}
}
}
```
1.先判断质数在判断回文数
#include <stdio.h>
#include <math.h>
int main(){
int a,b;
scanf("%d %d",&a,&b);
int k=0,sum=0;//k为开关,如果k还是0,说明就为质数
for(int i=a;i<=b;i++)
for(int j=2;j<=sqrt(i);j++){{//判断是否为质数,现将要判断的数i进行开方,再用i依次除以2至i开方所得的值,如果除开则k=1,跳出循环
if(i%j==0){
k=1;
break;
}
}
if(k==0){//k==0为质数,进行回文数判断
int m=i;
while(m/10!=0){//判断条件
int b=m%10;//先求出余数
sum=(sum+b)*10;//每循环一次就相加乘以10
m=m/10;//进行除以10
}
sum=sum+m;//最后加上m的值是个位,就全部逆转了
//可以以101为例子:b=101%10=1;sum=(0+1)*10=10;m=10 第一次循环
// b=10%10=0;sum=(0+10)*10=100;m=1 第二次循环
// 1/10==0 结束循环 当前sum值为100,最后一个为个位数相加,100+1=101
if(sum==i){//相等输出
printf("%d\n",i);
}
sum=0;
}
k=0;
}
return 0;
}
但是这个还是超出了,时间限制,所以换了个比这个时间少的也就是先判断回文数,再判断质数
2.先判断回文数,再判断质数
#include <stdio.h>
#include <math.h>
int main(){
int a,b;
scanf("%d %d",&a,&b);
int k=0,sum=0;
for(int i=a;i<=b;i++){
int m=i;
if(m%2==0){//多了个这个判断,因为偶数没有回文数,所以遇到偶数直接跳过
continue;
}else{
while(m/10!=0){
int b=m%10;
sum=(sum+b)*10;
m=m/10;
}
sum=sum+m;
if(sum==i){
for(int j=2;j<=sqrt(i);j++){
if(i%j==0){
k=1;
break;
}
}
if(k==0){
printf("%d\n",i);
}
k=0;
}
sum=0;
}
}
return 0;
}
这个先判断回文数,比上一个代码节省了时间,但最后还是得了88分,最后输入5 100000000的时候,还是会超时为1.2s。
本人也是刚开始练习,也想不到好的解决办法了,希望有大佬留言,指点指点。