题目描述
如果一个数字既是素数也是回文数,就称这个数是回文素数
现在给定一个区间[L, R],希望你能求出在这个区间内有多少个回文素数。
输入
输入包括多组测试用例
每组测试用例包含两个整数L和R(1 ≤ L ≤ R ≤ 10^7)
输出
输出只有一个数字,代表 [L,R] 内回文素数的数量。
示例
输入: 100 120
输出: 1
解释: [100, 120]范围内共一个回文素数101。
思路
先建立范围内(1~10^7)素数表,在建表过程中建立回文素数线性表。整个过程在所有输入之前完成。处理每个输入时,直接在回文素数线性表中搜索
实现
语言:c++
#include <iostream>
#include <math.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define MAX 10000000
#define MAXDIGLEN 8
bool conditions[MAX+1];
int rvps[MAX];
int amoRvps;
void fillNumsAndRvps();
bool isRevEql(int);
int find(int);
int main(int argc, char** argv) {
int left,right;
int no;
int num;
int amo;
//建立素数表和回文素数线性表
fillNumsAndRvps();
while(scanf("%d",&left)!=EOF){
scanf("%d",&right);
amo=0;
no = find(left);
while(true){
if(no>=amoRvps) break;
num = rvps[no];
if(num>right){
break;
}else{
amo++;
//printf("%d\n",num);
}
no++;
}
printf("%d\n",amo);
}
return 0;
}
void fillNumsAndRvps(){
int n=MAX;
int lim = (int)sqrt(n);
rvps[0] = 2;
amoRvps = 1;
for(int i=4;i<=n;i+=2){
conditions[i]=true;
}
for(int i=3;i<=n;i+=2){
if(!conditions[i]){
// i为质数
if(isRevEql(i)){
rvps[amoRvps] = i;
amoRvps++;
//printf("%d\n",i);
}
if(i<=lim){
for(int j=i*i;j<=n;j+=(i<<1)){
conditions[j] = true;
}
}
}
}
}
bool isRevEql(int num){
int digLen=0;
int digs[MAXDIGLEN];
int temp;
while(num!=0){
temp=num/10;
digs[digLen] = num - (10*temp);
digLen++;
num = temp;
}
for(int i=0;i<digLen/2;i++){
if(digs[i]!=digs[digLen-1-i]) return false;
}
return true;
}
int find(int aim){
int left = 0;
int right = amoRvps-1;
int mid;
int num;
while(left<right){
mid=(left+right)/2;
num = rvps[mid];
if(num==aim) return mid;
if(num<aim){
left = mid+1;
}else{
right = mid;
}
}
if(rvps[left]>=aim) return left;
else return (left+1);
}