描述
一个数如果从左往右读和从右往左读数字是相同的,则称这个数是回文数,如121,1221,15651都是回文数。给定位数n,找出所有既是回文数又是素数的n位十进制数。(注:不考虑超过整型数范围的情况)。
输入
位数n,其中1<=n<=9。
输出
第一行输出满足条件的素数个数。
第二行按照从小到大的顺序输出所有满足条件的素数,两个数之间用一个空格区分。
样例输入
1
样例输出
4
2 3 5 7
这道题当初折磨了我很久才做出来了的。。。
分析:
首先如果枚举的话肯定会超时,这道题的数据范围太大了,当输入为9的时候就要枚举几亿个数,还要判断是否为回文和素数,超时是稳稳的。
那我们的切入点就在回文这里,因为回文是左右对称的,所以我们就可以从回文的对称性切入。例如输入为4时我们可以只从10枚举到99,然后将这些数对称过去就直接得到了4位数的回文,再判断是否为素数即可。
实现代码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <algorithm>
#include <iomanip>
#define LL long long
const int N=1e5;
using namespace std;
bool is_ss(int x) //判断x是否为素数
{
int n=sqrt(x);
for(int i=2;i<=n;i++)
if(x%i==0) return false;
return true;
}
int hwss(int x,int n) //将x对折,使其变为回文
{
int t=x;
if(n%2) x/=10; //因为有奇数位的数的中间一位不用对折,所以将x除10
while(x) //进行对折操作
{
t=t*10+x%10;
x/=10;
}
return t; //返回对折后的数
}
int main()
{
int n,m,k=1,a[N]; //因为要输出有多少个数,所以要把折叠后的回文储存下来
cin>>n;
if(n==1) {cout<<4<<endl<<"2 3 5 7"; return 0;}
m=(n+1)/2;
for(int i=1;i<m;i++) k*=10;
int num=0;
for(int i=k;i<k*10;i++) //枚举每一个数并进行折叠判断操作,并将该数储存
{
int u=hwss(i,n);
if(is_ss(u)) a[++num]=u;
}
cout<<num<<endl;
for(int i=1;i<=num;i++)
cout<<a[i]<<" ";
return 0;
}