回文质数
时限:1000ms 内存限制:10000K 总时限:3000ms
描述:
因为151即是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。 写一个程序来找出范围[a,b](5 <= a < b <= 100000000)间的所有回文质数;
输入:
单独一行,两个长整型数,a,b(以空格隔开)。
输出:
从小到大,输出一个回文质数的列表,一行一个。
输入样例:
5 500
输出样例:
5 7 11 101 131 151 181 191 313 353 373 383
#include <iostream> #include <string> #include <math.h> using namespace std; int myarray[10]; int judgePrimeNumber(int data) { for(int i=3;i<=sqrt(data);i+=2) //判断质数 if(data%i==0) return 0; return 1; } int judgePalindromenumber(int data) { int length=0; while(data!=0) { myarray[length]=data%10; data/=10; length++; } for(int i=0;i<length/2;i++) if(myarray[length-i-1]!=myarray[i]) return 0; return 1; } int main() { int min,max; cin>>min>>max; if(min%2==0) //min为偶数 for(int i=min+1;i<=max;i+=2) { if(judgePalindromenumber(i)&&judgePrimeNumber(i)) cout<<i<<endl; } else //min为奇数 { for(int i=min;i<=max;i+=2) if(judgePalindromenumber(i)&&judgePrimeNumber(i)) cout<<i<<endl; } }
参看http://zrj.me/archives/506;别人的思路不是打表,而是先判断回文,再判断质数,而是质数判断就直接穷举去除,看到他的最好的方法方法四是 0.5 秒,于是照着这个思路,重新搞,简单分析可以知道,任何一个 k 位正整数都可以产生一个 2*k 位和一个 2*k-1 位两个回文整数,例如,12 可以产生 121 和 1221 这两个,然后我们又知道,1 亿以内最大的数就是 99999999 了,8 个 9,那产生的时候最大也就 4 位数就可以了,照着这个思路,得到如下比较屌一点的代码:
#include <stdio.h> #include <math.h> #include <time.h> int is_prime(int x) { for (int i=2; i<sqrt(x+0.5); i++) { if (x%i == 0) { return 0; } } return 1; } void gener_palin() { for (int i=1; i<10000; i++) { // 根据 k 位数 i 产生 2*k 位的回文数 int cpy = i, sum; for (sum=i; cpy!=0; cpy/=10) { sum = sum*10 + cpy%10; } if (is_prime(sum)) { printf("%dn", sum); } // 产生 2*k-1 位的回文数 cpy = i/10; for (sum=i; cpy!=0; cpy/=10) { sum = sum*10 + cpy%10; } if (is_prime(sum)) { printf("%d\n", sum); } } } int main() { gener_palin(min,max); printf("%lf\n", (double)clock()/CLOCKS_PER_SEC); return 0; }