原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1431
素数回文
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18470 Accepted Submission(s): 4295
Problem Description
xiaoou33对既是素数又是回文的数特别感兴趣。比如说151既是素数又是个回文。现在xiaoou333想要你帮助他找出某个范围内的素数回文数,请你写个程序找出 a 跟b 之间满足条件的数。(5 <= a < b <= 100,000,000);
Input
这里有许多组数据,每组包括两组数据a跟b。
Output
对每一组数据,按从小到大输出a,b之间所有满足条件的素数回文数(包括a跟b)每组数据之后空一行。
Sample Input
5 500
Sample Output
5 7 11 101 131 151 181 191 313 353 373 383
定理:如果一个数是回文数且是偶数位,那么一定能被11整除。
所以1亿的范围缩小为1千万,因为8位数不存在素数回文数,因为是回文数必不是素数。
这样打表就不会超过限定了。
#include<iostream>
using namespace std;
const int maxn = 10000000 + 1;
bool init[maxn];
char str[20];
void get_init() {
memset(init, true, sizeof(init));
for (int i = 2;i < maxn;i++) {
if (init[i]) {
for (int j = i + i;j < maxn;j += i)
init[j] = false;
}
}
}
int check_isHuiwen(int n) {
int k = 0;
while (n) {
str[k++] = n % 10;
n /= 10;
}
int len = k - 1;
for (int i = 0;i < len - i;i++) {
if (str[i] != str[len - i])
return 0;
}
return 1;
}
int main() {
get_init();
int x, y;
while (cin >> x >> y) {
int flag = 0, temp;
if (x > y) {
temp = y;
y = x;
x = temp;
}
if (y>maxn - 1)
y = maxn - 1;
for (int i = x;i <= y;i++) {
if (init[i]) {
int flag = check_isHuiwen(i);
if (flag)
cout << i << endl;
}
}
cout << endl;
}
}
不打表做法,要先判断是不是回文数,再判是不是素数,毕竟回文数少
代码:
#include<iostream>
using namespace std;
const int maxn = 9989899 + 1;
char str[20];
int isPrime(int n) {
if (n == 2) return 1;
if (n % 2 == 0) return 0;
for (int i = 3;i*i <= n;i += 2)
if (n%i == 0)
return 0;
return 1;
}
int check_isHuiwen(int n) {
int k = 0;
while (n) {
str[k++] = n % 10;
n /= 10;
}
int len = k - 1;
for (int i = 0;i < len - i;i++) {
if (str[i] != str[len-i])
return 0;
}
return 1;
}
int main() {
int x, y;
while (cin >> x >> y) {
int flag = 0,temp;
if (x > y) {
temp = y;
y = x;
x = temp;
}
if (y>maxn-1)
y = maxn-1;
for (int i = x;i <= y;i++) {
if (check_isHuiwen(i)) {
int flag = isPrime(i);
if (flag)
cout << i << endl;
}
}
cout << endl;
}
}
此外判断是不是回文数,我的代码有点不好,其实有更好的代码比如,把数倒着生成一遍,如果与原数相同,就是回文数。
bool check(int x)
{
int a=x;
int b=0;
while(a)
{
b=b*10+a%10;
a/=10;
}
return b==x;
}