题目描述
因为 151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151 是回文质数。
写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)[a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。
输入格式
第一行输入两个正整数 aa 和 bb。
输出格式
输出一个回文质数的列表,一行一个。
输入输出样例
输入 #1
5 500
输出 #1
5 7 11 101 131 151 181 191 313 353 373 383
解题分析
首先就要注意一下题目的数据量,1000000000的话,哪怕只是对每个数字进行一个简单的枚举都会超过限制的时间1s,所以,我们要缩小我们循环枚举的范围。
实际上,对于回文数来说,我们是可以自己“造”出来的,而回文数的数量显然没有那么多,所以我们只需要一个高效的判断质数的方法和一个简单粗暴的限制范围枚举就可以解决本题了。
代码展示
#include <iostream>
#include <cmath>
#define right (cycle >= a && cycle<= b)
using namespace std;
bool prime(int n){
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
return 0;
}
}
return 1;
}
int main(){
int a,b,cycle;
cin>>a>>b;
for(int i=2;i<=9;i++){
cycle=i;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
if(b<=9) goto flag;
for(int d1=1;d1<=9;d1+=2){
cycle=d1*10+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
if(b<=100) goto flag;
for(int d1=1;d1<=9;d1+=2){
for(int d2=0;d2<=9;d2++){
cycle=100*d1+10*d2+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
}
if(b<=1000) goto flag;
for(int d1=1;d1<=9;d1+=2)
for(int d2=0;d2<=9;d2++){
cycle=d1*1000+d2*100+d2*10+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
if(b<=10000) goto flag;
for(int d1=1;d1<=9;d1+=2)
for(int d2=0;d2<=9;d2++)
for(int d3=0;d3<=9;d3++){
cycle=d1*10000+d2*1000+d3*100+d2*10+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
if(b<=100000) goto flag;
for(int d1=1;d1<=9;d1+=2)
for(int d2=0;d2<=9;d2++)
for(int d3=0;d3<=9;d3++){
cycle=d1*100000+d2*10000+d3*1000+d3*100+d2*10+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
if(b<=1000000) goto flag;
for(int d1=1;d1<=9;d1+=2)
for(int d2=0;d2<=9;d2++)
for(int d3=0;d3<=9;d3++)
for(int d4=0;d4<=9;d4++){
cycle=d1*1000000+d2*100000+d3*10000+d4*1000+d3*100+d2*10+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
if(b<=10000000) goto flag;
for(int d1=1;d1<=9;d1+=2)
for(int d2=0;d2<=9;d2++)
for(int d3=0;d3<=9;d3++)
for(int d4=0;d4<=9;d4++){
cycle=d1*10000000+d2*1000000+d3*100000+d4*10000+d4*1000+d3*100+d2*10+d1;
if(prime(cycle) && right){
cout<<cycle<<endl;
}
}
flag:
return 0;
}