中文题目链接:http://www.nocow.cn/index.php/Translate:USACO/pprime
同样是搜索题,可以理解为深搜也可以理解为暴力搜索。
搜索的范围是10^8,显然100000000不是质数, 所以考虑回文数的一半的范围是1-9999, 所有的1-9999999之间的数都可以由此构造而来。
对于1-9999之间的任意一个数,都有机会构造成两个回文数(奇数位数和偶数位数),这样做的好处是省去了判断是否是回文的繁琐和深搜所需要的递归调用。
为了判断质数的效率牺牲了代码的简洁性, STL的一些库函数也可以让代码更简单。
/*
PROG: pprime
LANG: C++11
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <deque>
#include <set>
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <time.h>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
#define eps 10e-8
typedef long long ll;
const int N = 100010;
const ll MOD = 1000000007;
const int INF = 0x7fffffff;
const int MAX = 100000000;
vector<int> primes;
vector<int> palidromes;
vector<int> solution;
ifstream fin ("pprime.in");
ofstream fout("pprime.out");
int a, b;
// for generating the prime list
bool simpleCheck(int x){
if(!(x%2)) return false;
for(int z = 3; z*z <= x; z= z+2){
if(x%z == 0)
return false;
}
return true;
}
// generating the prime number list under 10000
void listPrimes(){
primes.push_back(2);
for(int i = 3; i<= 10000; i = i+2){
if(simpleCheck(i)){
primes.push_back(i);
}
}
}
// check primity fast, though slower than seive
bool isPrime(int x){
for(int i = 0; i < primes.size(); i++){
if(x == primes[i])
return true;
if(x%primes[i] == 0)
return false;
}
return true;
}
int digits(int x){
int i = 1;
while(x >= 10){
x /= 10;
i++;
}
return i;
}
int pow10(int p){
int ans = 1;
while(p--){
ans *= 10;
}
return ans;
}
int reverse1(int x){
int ans = 0;
while(x > 0){
ans *= 10;
ans += x%10;
x /= 10;
}
return ans;
}
int reverse2(int x){
int ans = 0;
x /= 10;
while(x > 0){
ans *= 10;
ans += x%10;
x /=10;
}
return ans;
}
void generatePal(){
for(int i = 1; i <= 9999; i++){
// two options for generating the palidrome
int n = digits(i);
int num1 = i * pow10(n) + reverse1(i);
if(num1 >= a && num1 <= b && isPrime(num1)){
solution.push_back(num1);
}
int num2 = i * pow10(n-1) + reverse2(i);
if(num2 >= a && num2 <= b && isPrime(num2)){
solution.push_back(num2);
}
}
}
int main()
{
int i, j;
fin >> a >> b;
listPrimes();
generatePal();
sort(solution.begin(), solution.end());
for(int i = 0; i < solution.size(); i++){
fout << solution[i] << endl;
}
return 0;
}