题目描述
给定a,b(1<a,b<10,000,000,000)请求出所有在这两个数范围内,既是回文又是质数的数字。
题目思路
因为范围过于大,如果遍历范围内的每一个数字,判定是否为质数?是否为回文?复杂度过高。
问题是缩小范围。
首先,位数是偶数的回文数字必是11的倍数(除11本身)(例如 2112=11*192),所以1000万到1亿之间不可能存在回文质数,将范围缩小至1000万。
很多选择枚举范围的做法,这里写一下自己想的生成回文,比如数字b翻转过来是d,那么可以生成三类回文:b本身、bd、b?d(?是0~9),例如 (b=123 123、123321、1230321……1239321)。
在回文集合中判定每一个回文数是否为质数,最后排序及去重输出。
#include<bits/stdc++.h>
using namespace std;
#define Max 3162
int n,m,k,i,j,cnt,a,b;
int ans[100010],tmp[12];
bool check(int x){//判断是否为质数
if(x<a||x>b) return false;
for(int i=2;i<=sqrt(x);i++){
if(x%i==0) return false;
}
return true;
}
bool checkP(int x){//检查是否回文
int t[20],tnum=0;//t为保存数字的数组,tnum为下标
while(x){
t[++tnum]=x%10;
x/=10;
}
for(int i=1;i<=tnum/2;i++){
if(t[i]!=t[tnum-i+1]) return 0;
}
return 1;
}
int compent(int x){
int t=x;
tmp[1]=x;
while(t){
tmp[1]=tmp[1]*10+t%10;
t/=10;
}
for(int i=0;i<10;i++){
t=x;
tmp[i+2]=x*10+i;
while(t){
tmp[i+2]=tmp[i+2]*10+t%10;
t/=10;
}
}
}
int main()
{
cin>>a>>b;
for(i=1;i<3162;i++){//i ii i?i
if(checkP(i)) tmp[0]=i;
else tmp[0]=4;
compent(i);//形成 ii 及 i?i
for(j=0;j<12;j++){
if(check(tmp[j])) ans[++cnt]=tmp[j];
}
}
sort(ans+1,ans+1+cnt);
for(i=1;i<=cnt;i++){
if(ans[i]!=ans[i-1]) cout<<ans[i]<<endl;
}
}