题目大意:
输出l~r之间既回文也是质数的数。
思路:
由于l和r最大为100000000,遍历l~r的话必定超时,所以需要新的思路。
其实从5~100000000里面的回文数并不多(测试后19994个),所以我们可以选择构造回文数。回文数有两种构造方法:
1、123 -> 123321
2、123 -> 12321
所以,我们可以用dfs遍历出所有的回文数,然后再从回文数中找质数,时间复杂度O(n*sqrt(1e8))。
#include<bits/stdc++.h>
using namespace std;
int a[20000],sum=1,now[10],l,r;//a存回文数,now存每一位的数字
void dfs(int len){
if(len!=0){
for(int i=1;i<=len;i++){
a[sum]=a[sum]*10+now[i];
}
for(int i=len;i>=1;i--){
a[sum]=a[sum]*10+now[i];
}
sum++;
for(int i=1;i<=len;i++){
a[sum]=a[sum]*10+now[i];
}
for(int i=len-1;i>=1;i--){
a[sum]=a[sum]*10+now[i];
}
sum++;
}
if(len==4){//如果长度为4,那回文数长度就为8,不行
return;
}
int flag=0;
if(len==0){//首位不是0
flag=1;
}
for(int i=flag;i<=9;i++) {
now[len+1]=i;
dfs(len+1);
now[len+1]=0;//回溯
}
}
bool check(int x){//判断质数
for(int i=2;i<=sqrt(x);i++){
if(x%i==0){
return false;
}
}
return true;
}
int main(){
dfs(0);
cin>>l>>r;
sort(a+1,a+sum+1);
for(int i=1;i<=sum;i++){
if(a[i]>=l&&a[i]<=r) {
if(check(a[i])){
cout<<a[i]<<"\n";
}
}
}
return 0;
}