The number 151 is a prime palindrome because it is both a prime number and a palindrome (it is the same number when read forward as backward). Write a program that finds all prime palindromes in the range of two supplied numbers a and b (5 <= a < b <= 1000,000,000); both a and b are considered to be within the range .
素数回文数判定,数据范围大,对时间要求较为严苛。
下以8位数为例,证明偶数位数的回文数都不是prime number
转自liujiacongBaBa https://blog.youkuaiyun.com/jc514984625/article/details/53461821
设x=10000001i+1000010j+100100k+11000l(i为1-9的自然数,j,k,l为0-9的自然数)
分解得x=11(909091i+90910j+9100k+1000l)
又909091i+90910j+9100k+1000l>2
∴11|x
x必定为合数
同理可得当回文数x的位数为偶数位时必有11|x当x/11>2时x必为合数
直接枚举回文数的前几位,使用mir函数计算整个数字(如果枚举后几位可能会在末尾的0处出现问题),使用is_prime判断是否素数并输出
#include <stdio.h>
#include <string.h>
#include <math.h>
int a, b;
int x;
int ans;
int t;
int is_prime(int p) {
if (p == 1) return 0;
int x2 = sqrt(p) + 1;
for (int i = 2; i <= x2; i++) {
if (p % i == 0) return 0;
}
return 1;
}
int mir(int ori, int base, int po) {
ans = 0;
t = ori / 10;
for (int i = 1; i <= base; i++) {
ans *= 10;
ans += (t % 10);
t /= 10;
}
return (ans + ori * po);
}
void check(int base) {
int tcheck = 1;
for (int i = 1; i <= 2 * base - 2; i++) tcheck *= 10;
if (tcheck > b) return;
tcheck = 9;
for (int i = 1; i <= 2 * base - 2; i++) {
tcheck *= 10;
tcheck += 9;
}
if (tcheck < a) return;
int imin = 1;
for (int i = 1; i < base; i++) imin *= 10;
// if (imin > b) return;
int imax = 9;
for (int i = 1; i < base; i++) {
imax *= 10;
imax += 9;
}
for (int i = imin; i <= imax; i++) {
x = mir(i, base - 1, imin);
if (x == 9) x = 11;
if (x < a || x > b) continue;
if(is_prime(x)) printf("%d\n", x);
}
// if (imax < a) return;
// printf("%d %d %d\n", base, imin, imax);
}
int main () {
scanf("%d %d", &a, &b);
for (int i = 1; i <= 5; i++) {
// if (i % 2 == 0) continue;
check(i);
}
// printf("%d", mir(15550, 4, 10000));
return 0;
}