P1217. Prime Palindromes

考点

  • 枚举
  • 质数
  • 回文数

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <bits/stdc++.h>

using namespace std;

bool isPalindrome(int x)
{
int arr[11], idx = 0;
do
{
arr[idx++] = x % 10;
x /= 10;
} while (x);
for (int i = 0, j = idx - 1; i < j; ++i, --j)
if (arr[i] != arr[j])
return false;
return true;
}

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

int main()
{
int a, b;
cin >> a >> b;
if (b > 9999999)
b = 9999999;
for (int i = (a % 2 ? a : a + 1); i <= b; i += 2)
{
if (isPalindrome(i) && isPrime(i))
cout << i << endl;
}
return 0;
}

思路

本题更多地是考验数论的能力.....

  • 如果一个数是11的倍数,那么奇数位置的和等于偶数位置的和;也就是说,11的倍数其实都是长度为偶数的回文数

    所以可以提前剪枝,大于9999999的数都可以不用判断,因为就算是回文数也绝对不可能是质数

  • 如果一个数是偶数,自然也不可能是质数,也可以借助这个特性再次剪枝

  • 还有一个优化点,回文数的个数肯定是远小于质数的个数;所以判断回文数的操作应该放在判断质数之前,大幅减少时间开销