【素数】P1217 [USACO1.5]回文质数 Prime Palindromes

寻找回文素数
本文介绍了一种高效求解5到1e8范围内回文素数的方法,通过生成所有可能的回文数并筛选出素数,利用二分查找快速定位特定范围内的回文素数。

https://www.luogu.com.cn/problem/P1217
考点:素数、回文、二分、打表
在这里插入图片描述题意:
找出5到1e8的回文素数。

解法:
直接暴力遍历1亿次必定超时,可以用打表法。。。

我的解法是列出1位到8位的所有回文数(不到2万个),再把不是素数的去掉。符合条件的回文素数存在vector中,根据输入范围用二分找出上下界打印即可。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

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

int main() {
	vector<string> v1,v2,v3,v4,v5,v6,v7,v8;
	//ll a,b; cin >> a >> b;
	for (int i = 0; i <= 9; i++) v1.push_back(to_string(i));
	for (int i = 0; i <= 9; i++) v2.push_back(to_string(i)+to_string(i));
	for (int i = 0; i <= 9; i++) {
		for (auto &s : v1) {
			v3.push_back(to_string(i) + s + to_string(i));
		}
	}
	for (int i = 0; i <= 9; i++) {
		for (auto &s : v2) {
			v4.push_back(to_string(i) + s + to_string(i));
		}
	}
	for (int i = 0; i <= 9; i++) {
		for (auto &s : v3) {
			v5.push_back(to_string(i) + s + to_string(i));
		}
	}
	for (int i = 0; i <= 9; i++) {
		for (auto &s : v4) {
			v6.push_back(to_string(i) + s + to_string(i));
		}
	}
	for (int i = 0; i <= 9; i++) {
		for (auto &s : v5) {
			v7.push_back(to_string(i) + s + to_string(i));
		}
	}
	for (int i = 0; i <= 9; i++) {
		for (auto &s : v6) {
			v8.push_back(to_string(i) + s + to_string(i));
		}
	}
	vector<int> v;
	for (auto &s:v1) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v2) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v3) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v4) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v5) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v6) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v7) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	for (auto &s:v8) if (s[0]!='0' && prime(stoi(s))) v.push_back(stoi(s));
	int a,b; cin >> a >> b;
	int lb = lower_bound(v.begin(), v.end(), a) - v.begin(); // 第一个大于等于a的下标
	int ub = upper_bound(v.begin(), v.end(), b) - v.begin() - 1; // 第一个大于b的下标-1
	for (int i = lb; i <= ub; i++) cout << v[i] << endl;

    return 0;
}

看了别人的题解,发现比较流行的做法是用埃筛或欧筛把素数筛出来再判断回文。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值