思路一
- 筛出(10^7)以内素数
- 判断素数表中的数是否为回文数
注意点
- 如果一个回文数的位数是偶数,则它的奇数位上的数字和与偶数位上的数字和必然相等,这样的数能被11整除,不可能是素数(11自己除外)。
- 由上条性质,素数表只要筛到(10^7)即可。
- USACO上提交居然MLE?遂放弃记录素数表,直接用标记数组判断某个数是否为素数。
const int N=1e7+10;
bool vis[N];
int l,r;
void init(int n)
{
for(int i=2;i*i<=n;i++)
if(!vis[i])
{
for(int j=i;j<=n/i;j++)
vis[i*j]=true;
}
}
bool check(int x)
{
string s=to_string(x);
for(int i=0;i<s.size()/2;i++)
if(s[i] != s[s.size()-1-i])
return false;
return true;
}
int main()
{
init(N-1);
cin>>l>>r;
for(int i=l;i<=min(r,(int)1e7);i++)
if(!vis[i] && check(i))
cout<<i<<endl;
//system("pause");
return 0;
}
思路二
- 生成所有回文数
- 判断回文数是否为素数
由于位数和各位数字均按照从小到大顺序进行枚举,所以可直接输出。
int l,r;
bool isprime(int x)
{
if(x < 2) return false;
for(int i=2;i*i<=x;i++)
if(x % i == 0)
return false;
return true;
}
void dfs(int u,string s,int n)
{
if(u == (n+1)/2)
{
string t=s.substr(0,n/2);
reverse(t.begin(),t.end());
s+=t;
int x=stoi(s);
if(x >= l && x <= r && isprime(x))
cout<<x<<endl;
return;
}
else
{
for(int i=0;i<=9;i++)
{
if(u == 0 && i == 0) continue; // 首位不为0
dfs(u+1,s+char(i+'0'),n);
}
}
}
int main()
{
cin>>l>>r;
for(int i=1;i<=8;i++)
dfs(0,"",i);
//system("pause");
return 0;
}