题目传送门:P1217 [USACO1.5] 回文质数 Prime Palindromes - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目描述
因为 151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151 是回文质数。
写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。
输入格式
第一行输入两个正整数 a 和 b。
输出格式
输出一个回文质数的列表,一行一个。
输入输出样例
输入 #1
5 500
输出 #1
5 7 11 101 131 151 181 191 313 353 373 383
那么废话不多说,直接上解析
先创建一个数组,至于为什么,待会会解释,我们得先算出5到500的回文质数,至于return就随便返回。
void init(int mmax){
for(int i=2;i<=mmax;i++){
if(arr[i]) continue;
for(int j=i;j<=mmax/i;j++){
arr[i*j]=1;
}
}
return ;
}
再写一个判断回文数的函数,定义一个数再进行模10除10的操作,如果倒着的数等于原来的数就返回1,否则返回0,这里可以用三目运算符。
int h(int n){
int copy=n;
int temp=0;
while(copy){
temp*=10;
temp+=copy%10;
copy/=10;
}
return (n==temp ? 1:0);
}
再写一个大家都会的主函数,注意arr和函数的区别,先判断是不是质数,在判断是不是回文数会更快一点
int main(){
int a,b;
cin>>a>>b;
init(b);
for(int i=a;i<=b;i++){
if(arr[i]==0 && h(i)) printf("%d\n",i);
}
return 0;
}
先将算出5到500的回文质数删掉
真是泰裤辣!
再将判断加上,这个时候我们把代码上交至洛谷
#include<iostream>
using namespace std;
int arr[99999999];
void init(int mmax){
for(int i=2;i<=mmax;i++){
if(arr[i]) continue;
for(int j=i;j<=mmax/i;j++){
arr[i*j]=1;
}
}
return ;
}
int h(int n){
int copy=n;
int temp=0;
while(copy){
temp*=10;
temp+=copy%10;
copy/=10;
}
return (n==temp ? 1:0);
}
int main(){
int a,b;
cin>>a>>b;
init(b);
for(int i=a;i<=b;i++){
if(arr[i]==0 && h(i)) printf("%d\n",i);
}
return 0;
}
可以发现我们成功的没有AC,因为最后一个点MLE,也就是内存爆炸了,但是从原来的11分突破至88分
而最后一个点给的数据非常恶心,输入是5 1000000
所以我们要加一个判断后面输入的b是不是大于1亿,因为超过1亿及以上就会爆栈,
if(b>=10000000)b=9999999;
再将这个判断加入代码中
#include<iostream>
using namespace std;
bool arr[99999999];
void init(int mmax){
for(int i=2;i<=mmax;i++){
if(arr[i]) continue;
for(int j=i;j<=mmax/i;j++){
arr[i*j]=1;
}
}
return ;
}
int h(int n){
int copy=n;
int temp=0;
while(copy){
temp*=10;
temp+=copy%10;
copy/=10;
}
return (n==temp ? 1:0);
}
int main(){
int a,b;
cin>>a>>b;
if(b>=10000000)b=9999999;
init(b);
for(int i=a;i<=b;i++){
if(arr[i]==0 && h(i)) printf("%d\n",i);
}
return 0;
}
可以看到我们是成功的AC了,妙啊