题目描述
因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以151是回文质数。
写一个程序来找出范围[a,b] (5<=a <b<=100,000,000)(一亿)间的所有回文质数。
输入格式
第一行输入两个正整数a和b。
输出格式
输出一个回文质数的列表,一行一个。
样例输入
5 500
样例输出
5
7
11
101
131
151
181
191
313
353
373
383
思路:
1.如果遍历a-b的数,肯定会超时(一亿);
2.首先有一个小技巧,偶数位数的数字除了11都不是回文质数(证明详见“3”),因此首先可以判断数字的位数,排除10-99,1000-9999和100000-999999的数字,而且,b最大不会超过9999999(大于9999999后位数为8);
3.设回文数为abba为例,a>0。如果a>b,abba/11=(a-1)(10+b-a)a;如果a<b,那么abba/11=a(b-a)a,总之,是11的倍数,非质数;
4.在回文数和质数中,回文数更少,可以再判断回文数,其次再判断质数;
5.判断质数遍历数字时,只需要遍历奇数即可。
#include<bits/stdc++.h>
using namespace std;
bool num(int i)//判断位数,可以把11当作非偶数位数的一类
{
if(i==11)return true;
else if((i>=10&&i<=99)||(i>=1000&&i<=9999)||(i>=100000&&i<=999999))
return false;
return true;
}
bool findnum(int i)//判断质数
{
for(int j=2;j<=sqrt(i);j++){
if(i%j==0)return false;
}
return true;
}
bool run(int i)//判断回文
{
int a[9];
int j=0,k=0;
while(i>0){
a[j++]=i%10;
i/=10;
}
j--;
for(;k<j;){
if(a[k]==a[j])k++,j--;
else return false;
}
return true;
}
int main()
{
int l,r;
cin>>l>>r;
if(l%2==0)l++;//把l调整为奇数
r=min(9999999,r);
for(int i=l;i<=r;i+=2){
if(num(i)){
if(run(i)){
if(findnum(i))cout<<i<<endl;
}
}
}
}