回文质数 Prime Palindromes(欧拉筛)

2024-01-06 10:08

本文主要是介绍回文质数 Prime Palindromes(欧拉筛),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

回文质数 Prime Palindromes

题目描述
因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。

写一个程序来找出范围 [a,b] (5 < a < b < 100,000,000)a,b( 一亿)间的所有回文质数。

输入格式
第 1 行: 二个整数 a 和 b .

输出格式
输出一个回文质数的列表,一行一个。

输入输出样例
输入
5 500
输出
5
7
11
101
131
151
181
191
313
353
373
383

PS:383后面是否有空行并不会检测

错误代码

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
#define Max 100000000 
bool IsSu[Max+1];
int Prime[Max];//存放素数的数组
bool IsHWS(int x)
{//思路将个位十百反转,若等于原数,则为回文数int k = x;//储存该数// k = k%10;//求出个位int nums = 0;//存储反转后数while(k!=0){nums = nums*10+k%10;k = k/10;}if(nums==x){return true;}else{return false;}
}int main()
{int a,b;scanf("%d%d",&a,&b);int t = 0;memset(IsSu,true,sizeof(bool)*(Max+1));if(b>=Max){b = Max-1;}//假设标记0为素数//用数组的下标作为素数for(int i=2;i<=b;i++)//遍历寻找素数{if(IsSu[i]==true){//如果是素数Prime[t] = i;t++;//记录素数的个数}for(int j=0;j<t&&i*Prime[j]<=b;j++){IsSu[Prime[j]*i] = false;if(i%Prime[j]==0){break;}}}if(a%2==0){a++;}for(int i=a;i<=b;i++){if(i>10000000) break;if(IsHWS(i)==true&&IsSu[i]==true){printf("%d\n",i);}}return 0;
}

问题分析

  1. 一开始根本不会回文数的判断方法,脑子里想的全是栈,然后又不知道什么时候停止入栈,什么时候出栈,结果直接看了大佬的代码,用变量接收x的一个个位上数字,再将个位作为最高位与原x比较
  2. 学了回文数判断后,用埃氏筛筛选素数,结果超时,又双看了大佬代码,学了欧拉筛,结果兴奋一试,还是超时,浪费n久后,终于发现:

偶数位数回文数(除11)必定不是质数(自行百度),所以只要运行到10000000

偶数位回文数会被11整除
这样只需要给b添加一个条件即可

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
#define Max 100000000 
bool IsSu[Max+1];
int Prime[Max];//存放素数的数组
bool IsHWS(int x)
{//思路将个位十百反转,若等于原数,则为回文数int k = x;//储存该数// k = k%10;//求出个位int nums = 0;//存储反转后数while(k!=0){nums = nums*10+k%10;k = k/10;}if(nums==x){return true;}else{return false;}
}int main()
{int a,b;scanf("%d%d",&a,&b);int t = 0;memset(IsSu,true,sizeof(bool)*(Max+1));if(b>=Max){b = Max-1;}//假设标记0为素数//用数组的下标作为素数for(int i=2;i<=b;i++)//遍历寻找素数{if(IsSu[i]==true){//如果是素数Prime[t] = i;t++;//记录素数的个数}for(int j=0;j<t&&i*Prime[j]<=b;j++){IsSu[Prime[j]*i] = false;if(i%Prime[j]==0){break;}}}if(a%2==0){a++;}if(b>10000000){b=10000000}for(int i=a;i<=b;i++){if(i>10000000) break;if(IsHWS(i)==true&&IsSu[i]==true){printf("%d\n",i);}}return 0;
}

总结

  1. 欧拉筛的使用
  2. 回文数的判断方法

这篇关于回文质数 Prime Palindromes(欧拉筛)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/576009

相关文章

csu1328(近似回文串)

题意:求近似回文串的最大长度,串长度为1000。 解题思路:以某点为中心,向左右两边扩展,注意奇偶分开讨论,暴力解即可。时间复杂度O(n^2); 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring>#include<string>#inclu

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

欧拉系统 kernel 升级、降级

系统版本  cat  /etc/os-release  NAME="openEuler"VERSION="22.03 (LTS-SP1)"ID="openEuler"VERSION_ID="22.03"PRETTY_NAME="openEuler 22.03 (LTS-SP1)"ANSI_COLOR="0;31" 系统初始 kernel 版本 5.10.0-136.12.0.

nyoj99(并查集+欧拉路+dfs)

单词拼接 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 5 描述 给你一些单词,请你判断能否把它们首尾串起来串成一串。 前一个单词的结尾应该与下一个单词的道字母相同。 如 aloha dog arachnid gopher tiger rat   可以拼接成:aloha.arachnid.dog.gopher.rat.tiger 输入 第一行是一个整

nyoj42(并查集解决欧拉回路)

一笔画问题 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下来。 规定,所有的边都只能画一次,不能重复画。   输入 第一行只有一个正整数N(N<=10)表示测试数据的组数。 每组测试数据的第一行有两个正整数P,Q(P<=1000,Q<

UVa 10820 Send a Table (Farey数列欧拉函数求和)

这里先说一下欧拉函数的求法 先说一下筛选素数的方法 void Get_Prime(){ /*筛选素数法*/for(int i = 0; i < N; i++) vis[i] = 1;vis[0] = vis[1] = 0;for(int i = 2; i * i < N; i++)if(vis[i]){for(int j = i * i; j < N; j += i)vis[j] =

【UVA】11584-Partitioning by Palindromes(动态规划)

动态规划。 如果 j + 1 ~ i是回文,那么 dp[i] = min=(dp[j] + 1);  判断j + 1~ i是不是回文可以进行预处理,方法是枚举中心,之后向两边伸张,(需要枚举2次,一次是偶数回文,一次是奇数回文) 13993253 11584 Partitioning by Palindromes Accepted C++ 0.132 2014-08-05 08:2

NYOJ 37 回文字符串(记忆化搜索)

OJ题目 : 戳这里~~ 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba"。当然,我们给你的问题不会再简单到判断一个字符串是不是回文字符串。现在要求你,给你一个字符串,可在任意位置添加字符,最少再添加几个字符,可以使这个字符串成为回文字符串。 输入 第一行给出整数N(0<N<100) 接下来的N行,每行一个字符串,每个字符串长度不超过1000.