题目链接:Click here~~
题意:
中文题不解释。练习了下打回文数。挺有成就感的,分享下。
解题思路:
先观察,1-9 中有 9 个回文数,10-99中有 9 个回文数,100-999中有 9*10 个回文数,1000-9999中有 9*10 个回文数……
不难分析出,[1,n] 区间内,回文数个数的级别是 O( 10 ^ ( |d/2 |) ) 的( d = log10(n) )。于是此题区间中共有 O( 10 ^ 4 ) 的回文数。
可以枚举出所有的回文数,然后判断他们是不是素数,把所有回文素数存成一个表,查询时二分即可。
复杂度大概O(10^4 * log(n) + log(10^4) * Q)。
#include <vector>
#include <stdio.h>
#include <algorithm>
using namespace std;
vector<int> ans;
bool is_prime(int x)
{
for(int i=2;i*i<=x;i++)
if(x%i == 0)
return false;
return true;
}
int reverse(int n)
{
int res = 0;
while(n)
{
int d = n % 10;
res = res*10 + d;
n /= 10;
}
return res;
}
void get_table()
{
ans.push_back(5);
ans.push_back(7);
for(int l=1,base=1;l<=4;l++,base*=10)
{
for(int i=base;i<base*10;i++)
{
int pre_half = i * base * 10;
int rev_half = reverse(i);
int num = pre_half + rev_half;
if(is_prime(num))
ans.push_back(num);
if(l == 4)
continue;
for(int mid=0;mid<10;mid++)
{
num = pre_half * 10 + mid * base * 10 + rev_half;
if(is_prime(num))
ans.push_back(num);
}
}
}
sort(ans.begin(),ans.end());
}
int main()
{
get_table();
int a,b;
while(~scanf("%d%d",&a,&b))
{
vector<int>::iterator l , r , it;
l = lower_bound(ans.begin(),ans.end(),a);
r = upper_bound(ans.begin(),ans.end(),b);
for(it=l;it!=r;it++)
printf("%d\n",*it);
puts("");
}
return 0;
}