P1217 [USACO1.5]回文质数
Prime Palindromes
题解
1.理解题意:
回文质数,它既是回文数,又是质数
我们可以先找出范围内所有回文数,再判断一下他是不是质数就得到回文质数啦
2.注意:
(1)如果一个数是质数,那么除了2,他一定是奇数,所以回文质数一定是奇数
(2)所有偶数位的回文数除了11都不是质数,所以回文质数一定是奇数位
Ps:所有偶数位的回文数都是11的倍数,所以除了11,他们都不是质数
(3)then,我们就枚举奇数位的回文数好啦,本题的数据范围
所以只需要枚举 1 位,3位,5位,7位的回文数
回文数的第一位和最后一位一定是奇数!!
3.我的代码说明:
(1)优化了一下,两位以内的回文数只有3个,也就是 5,7,11(咳咳咳,看题目范围),所以直接特判一下就好了
(2)枚举回文数的时候其实只需要枚举数位的一半,因为另一半直接回文过来了
(3)之前的代码把输入的数字当成字符串输入了,后来改着改着发现没有必要,就改回来正常数字输入了,代码缩短了好多
代码
#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<cstring> #include<cmath> #include<queue> #include<cstdlib> using namespace std; char s1[15],s2[15]; int lens1,lens2,startt,endd; int ans_num,ans[1000001],num; bool pss(int x) { for(int i=2;i<=sqrt(x);i++) if(x%i==0) return 0; return 1; } void hws(int k) { if(k==3) { for(int i=1;i<=9;i+=2) for(int j=0;j<=9;j++) { num=i*100+j*10+i; if(pss(num)) ans[++ans_num]=num; } } else if(k==5) { for(int i=1;i<=9;i+=2) for(int j=0;j<=9;j++) for(int x=0;x<=9;x++) { num=i*10000+j*1000+x*100+j*10+i; if(pss(num)) ans[++ans_num]=num; } } else if(k==7) { for(int i=1;i<=9;i+=2) for(int j=0;j<=9;j++) for(int x=0;x<=9;x++) for(int y=0;y<=9;y++) { num=i*1000000+j*100000+x*10000+y*1000+x*100+j*10+i; if(pss(num)) ans[++ans_num]=num; } } } int main() { scanf("%d",&startt); scanf("%d",&endd); if(5>=startt&&5<=endd) ans[++ans_num]=5; if(7>=startt&&7<=endd) ans[++ans_num]=7; if(11>=startt&&11<=endd) ans[++ans_num]=11; for(int i=3;i<=7;i+=2) { hws(i); } for(int i=1;i<=ans_num;i++) { if(ans[i]<startt) continue; if(ans[i]>=startt&&ans[i]<=endd) printf("%d " ,ans[i]); else break; } return 0; }