原题链接:STIPC-001_F.小郭快点给我爬
F.小郭快点给我爬
题目背景
在算法编程竞赛中,数学是十分重要的,而小郭的数学很差,只能拜托你们了。
相信同学们已经与 素数 邂逅了多次,那今天就再来会一会它吧。题目描述
众所周知,回文素数是指,对一个整数,从左向右和从右向左读其结果值相同且是素数,即称这个整数为回文素数。
例如:5、11、101
现给出两个整数 n n n、 k ( k ≥ 1 ) k(k \geq\ 1) k(k≥ 1) ,写一个程序找出从整数 n n n 开始的第 k k k 个回文素数并输出此回文素数 x x x ,若在数据范围内未找到符合要求的回文素数,则输出0。输入格式
第 1 行: 两个整数 n n n 和 k k k .
输出格式
输出从 n n n 开始的第 k k k 个回文素数.
输入输出样例
样例一:
输入:
101 101 101 1 1 1
输出:
101 101 101
样例二:
输入:
1 1 1 3 3 3
输出:
5 5 5
数据范围:
对于 60 % 60 \% 60% 的数据, 1 ≤ x ≤ 1 , 000 , 000 1 \le x \le 1,000,000 1≤x≤1,000,000。
对于 100 % 100 \% 100% 的数据, 1 ≤ x ≤ 100 , 000 , 000 1 \le x \le 100,000,000 1≤x≤100,000,000。
提示:
偶数位数的回文数(除11外)必定不是质数
题目解析:
本题是本场比赛的压轴题,防AK题,但由于采用的是IOI赛制,虽然对编程基础较薄弱的同学AC比较困难,但也能够骗分。
本题涉及知识点:构造回文数 + 埃式筛
构造回文数,因为偶数位数的回文数(除11外)必定不是质数,题目要求的是回文质数,则偶数位数的可以略过,这样就省去了很大的计算时间。
其次,题目中有涉及一个小坑,可能在数据范围内不会找到符合要求的数,此时我们需要输出0。
埃式筛的相关知识本处就不再讲解,优秀的讲解在很多平台上都可以找到。
AC代码(C++):
//压轴题(防AK),埃式筛 + 构造回文数
#include <iostream>
#include <cstdio>
#define MAXN 10000005
using namespace std;
int prime[MAXN];
bool pp[MAXN];
int vis[MAXN];
bool pd_h(int x)
{
int y = x, num = 0;//int y=x,防止x被改变
while (y != 0)
{
num = num * 10 + y % 10;//上一次数字的记录进位再加上下一位数
y /= 10;
}
if (num == x) return 1;
else return 0;
}
int main()
{
int a = 0, b = 1e9;
int cnt = 0;
if (b > 10000000) b = 10000000;
for (int i = 2; i <= b; i++)
{
if (!vis[i]) prime[cnt++] = i, pp[i] = 1;
for (int j = 0; j < cnt && i * prime[j] <= b; j++)
{
vis[i * prime[j]] = i;
if (i % prime[j] == 0) break;
}
}
int N, K, ans = 0;
cin >> N >> K;
for (int n = N, k = 1; k <= K; n++) {
if (pd_h(n) && pp[n])ans = n, k++;
}
cout << ans;
}