USACO: Prime Palindromes

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值