题目链接: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; }