对回文质数题目的一些思考

回文质数是洛谷中题号为P1217的一道题目。题目要求所设计的程序可以在短时间之内,从给定的范围之内(5到100000000)寻找到所有的回文质数。以下是我个人对该题目的一些思考。

想要找到回文质数有多种方法,一种是暴力枚举再通过相应的方法去判断,另一种是直接生成回文质数,还有一种是先生成质数再判断回文数。这些方法都有自己的优劣所在。不对其进行相应的处理都会导致最终的测试TLE。由于能力所限,并没有找到合适的生成回文数的方法,所以接下来对其余两种算法分别进行阐述:

// 以下是暴力枚举
cin >> a >> b;
    if(a % 2 == 0)
        a++;
    for(int i = a; i <= b; i += 2){
    // 以下所用函数分别为:是否是范围内,是否是回文数,是否是质数
        if(isEven(i) && isPrimeRev(i) && isPrime(i)){
            cout << i << endl;
        }
        if(i > 9989899) break;
    }

// 以下是生成质数(埃氏塞法)
bool book[100000001];
    memset(book, true, sizeof(book));
    book[1]=false;//1不是质数
    int n=sqrt(b);
    for (int i=2;i<=n;i++) {
        if (book[i]) {
            //质数的倍数绝对不是质数,把所有质数的倍数全部设为false
            for (int j=2;j<=b/i;j++)
                book[i*j]=false;  // i*j<=b 
        }
    }

当然,想要得到质数还可以使用其他的算法,后续会在其他的文章之中阐述。用上面的两种算法可以较为快速的筛选出符合题意的质数。

下面阐述如何快速的找出回文数。

// 从下列代码中不难得出,从0开始逐渐更新temp变量,并将需要判断的数不断地消去第一位数,即为大概的思路。
int isPrimeRev(int n){
    int temp = 0, m = n, flag = 0;
    while(n != 0){
        temp = temp * 10 + n % 10;
        n /= 10;
    }
    if (temp == m) flag = 1;
    return flag;
}

通过这两种方法,就可以实现快速得到相应的回文质数。

以下是我的解题代码:

#include<bits/stdc++.h>

using namespace std;

unsigned int a,b;

int isEven(int n){
    if((1000< n && n < 9999) || (100000 < n &&  n < 999999))
        return 0;
    return 1;
}

int isPrimeRev(int n){
    int temp = 0, m = n, flag = 0;
    while(n != 0){
        temp = temp * 10 + n % 10;
        n /= 10;
    }
    if (temp == m) flag = 1;
    return flag;
}

int isPrime(int n){
    if(n == 2)  return 1;
    for(int i = 2; i <= sqrt(n); i++){
        if(n % i == 0)  return 0;
    }
    return 1;
}

int main(){
    cin >> a >> b;
    if(a % 2 == 0)
        a++;
    for(int i = a; i <= b; i += 2){
        if(isEven(i) && isPrimeRev(i) && isPrime(i)){
            cout << i << endl;
        }
        if(i > 9989899) break;
    }
    return 0;
}

最后,其他筛选质数的方法,仍需整理一番。

上一篇
下一篇