P1217 [USACO1.5]回文质数 Prime Palindromes
P1217 [USACO1.5]回文质数 Prime Palindromes
题目描述
因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。
写一个程序来找出范围 [a,b] (5 \le a < b \le 100,000,000)[a,b](5≤a<b≤100,000,000)( 一亿)间的所有回文质数。
输入格式
第 1 行: 二个整数 a 和 b .
输出格式
输出一个回文质数的列表,一行一个。
输入输出样例
输入 #1
5 500
输出 #1
5 7 11 101 131 151 181 191 313 353 373 383
超时未通过的第一种代码:
#include <iostream> #include <cmath> using namespace std; bool Prime(int x) { if(x<=1) return false; for(int i=2;i<=sqrt(x);i++) { if(x%i==0) return false; } return true; } bool Palindromes(int x) { int n,m; m=0;n=x; while(n!=0) { m=m*10+n%10; n/=10; } if(m==x) return true; else return false; } int main() { int a,b; cin>>a>>b; for(int i=a;i<=b;i++) { if(Prime(i)&&Palindromes(i)) cout<<i<<endl; } return 0; }
提交结果:
因为第一种代码在a~b中找质数,又在a~b中找回文数,所以循环的次数增加,也就导致了上面的运行结果不通过(不通过是因为超时)。
对于上面的代码,我们可以进行优化:1.质数从a~b里找,回文数在质数里找;2.回文数从a~b里找,质数在回文数里找。
如果在质数里找回文数代码是:
#include <iostream> #include <cmath> using namespace std; bool Palindromes(int x) { int n,m; m=0;n=x; while(n!=0) { m=m*10+n%10; n/=10; } if(m==x) return true; else return false; } bool Prime(int x) { if(x<=1) return false; for(int i=2;i<=sqrt(x);i++) { if(x%i==0) return false; } Palindromes(x); } int main() { int a,b; scanf("%d %d",&a,&b); if(b>=9999999) b=9999999; //最大的回文质数处理 if(a%2==0)a++;//从2的倍数+1开始搜索 for(int i=a;i<=b;i++) { if(Prime(i)) { if(Palindromes(i)!=0) cout<<i<<endl; } } return 0; }
提交结果:
为什么在质数里找回文数不通过呢?是因为找质数是用for循环1次1次的循环,循环次数就会很多
而找回文数用while循环次数就会少一些了,因为while循环的次数并不是1次1次的循环,所以要从回文数里找质数。
下面是通过的两种代码:
通过的第一种代码:
#include <iostream> #include <cmath> using namespace std; bool Palindromes(int x) { int n,m; m=0;n=x; while(n!=0) { m=m*10+n%10; n/=10; } if(m==x) return true; else return false; } bool Prime(int x) { if(x<=1) return false; for(int i=2;i<=sqrt(x);i++) { if(x%i==0) return false; } Palindromes(x); } int main() { int a,b; scanf("%d %d",&a,&b); if(b>=9999999) b=9999999; //最大的回文质数处理 if(a%2==0)a++;//从2的倍数+1开始搜索 for(int i=a;i<=b;i++) { if(Palindromes(i)==0) continue; else if(Prime(i)) cout<<i<<endl; } return 0; }
通过的第二种代码:
#include<bits/stdc++.h> using namespace std; int a,b,s[10]; bool prime(int x)//判断质数 { int i; for(i=3;i<=sqrt(x);i++) if(x%i==0) return 0; return 1; } bool huiwen(int x)//判断回文 { int k,len=0,j; while(x!=0) { len++; s[len]=x%10; x/=10; } if(len==1) { s[len]=0; return 1; } for(k=1;k<=len/2;k++) if(s[k]!=s[len-k+1]) return 0; for(k=1;k<=len;k++) s[k]=0; return 1; } int main() { int i; cin>>a>>b; if(b>=9999999) b=9999999; //最大的回文质数处理 if(a%2==0)a++;//从2的倍数+1开始搜索 for(i=a;i<=b;i+=2)//2的倍数不为回文质数 { if(huiwen(i)==0) continue; else if(prime(i)) cout<<i<<endl; } return 0; }
以上这两种不同的解法,大家可以自行借鉴。