洛谷 P1217

发布时间 2023-12-13 13:46:20作者: 胖柚の工作室

原题链接:

一开始的思路:把数字转换成字符串类型并将字符串反转,若反转后的字符串和原来的字符串一致且该数是质数,则是回文质数。

#include <bits/stdc++.h>

using namespace std;

bool isPrime(int x) {
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i++) {
        if (x % i == 0) return false;
    }
    return true;
}

int main() {
    int a, b;
    scanf("%d%d", &a, &b);
    for (int i = a; i <= b; i++) {
        string x = to_string(i);
        string y = x;
        reverse(y.begin(), y.end());
        if (y == x && isPrime(i)) cout << i << "\n";
    }
}

此代码只能得到88/100分
image

需要注意的是,因为回文数比质数要少的多,所以应当先判断是否回文再判断质数。若if中&&的两个条件颠倒,则只能得到66/100分
image

思考:除了2是唯一的偶质数,其余的质数全是奇数,而题目规定\(5 \leqslant a < b\),因此只需枚举 \(a\)\(b\) 之间的所有奇数即可,这样可以减去一半的工作量。
此外判断回文的方式也可以优化,用数组记录每一位的数字,再看这个数组是否回文即可。

AC代码:

#include <bits/stdc++.h>

using namespace std;

bool isPrime(int x) {
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i++) {
        if (x % i == 0) return false;
    }
    return true;
}

bool check(int x) {
    int a[11], flag = 1;
    while (x > 0) {
        a[flag++] = x % 10;
        x /= 10;
    }
    for (int i = 1; i <= flag / 2; i++) {
        if (a[i] != a[flag - i]) return false;
    }
    return true;
}

int main() {
    int a, b;
    scanf("%d%d", &a, &b);
    if (a % 2 == 0) a++;
    for (int i = a; i <= b; i += 2) {
        if ( check(i) && isPrime(i)) printf("%d\n", i);
    }
    return 0;
}