Sicily 4190 Prime Palindromes

Description

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 <= 100,000,000); both a and b are considered to be within the range .

Input

There are multiple test cases.

Each case contains two integers, a and b.

a=b=0 indicates the end of input.

Output

For each test case, output the list of palindromic primes in numerical order, one per line.

 

Sample Input
 Copy sample input to clipboard
5 500
0 0
Sample Output
5
7
11
101
131
151
181
191
313
353
373

383

分析:我们要找的数需要满足两个条件:一个是质数,一个是回文,质数是没有规律的,但回文是有规律的,因此我们可以考虑找出a和b之间的回文数判断他们是不是质数。回文数怎么找呢?回文数因为左右对称,所以可以由左一半直接确定右一半,枚举1到9999之间的数,直接翻折就可以得到11到99999999之间2位,4位,6位,8位的所有回文数,翻折的时候最后一位作为中间位保留,就可以得到1到9999999之间1位,3位,5位,7位的所有回文数,就算a=5, b=100000000也只需要不到两万次枚举就找到了全部回文数。为了使判断大数据是否为质数时的效率更高,用筛法预处理10000以内的质数,判断一个数是否是质数时只用质数去试除,这样效率会略高一些。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;

#define MAXN 10000
bool Prime[MAXN+1];
int PrimeBin[1300];
int PrimeBinSize = 0;
bool isPrime(int x)          // need to optimal
{
	if(x == 1)	return false;
	for(int i = 2; i*i <= x; i++)
		if(x%i == 0)
			return false;
	return true;
}
void findPrime(int n)
{
	memset(Prime, true, sizeof(Prime));
	Prime[0] = false; Prime[1] = false;
	for(int i = 4; i <= n; i += 2) Prime[i] = false; // erase all the even 
	for(int i = 2; i <= n; i++)
		if(Prime[i]/* && isPrime(i)*/)
			for(int j = (i*i); j <= n; j += (i<<1))  // j = i*i!!!
				Prime[j] = false;
}
bool isBigPrime(int x)
{
	if(x == 1) return false;
	for(int i = 0; PrimeBin[i]*PrimeBin[i] <= x; i++)
		if(x%PrimeBin[i] == 0)
			return false;
	return true;
}
int PalindromePrime[800];
int PalindromePrimeSize = 0;
void Palindrome(int x, int *p)
{
	int tmp = 0; 
	int bit = 0;
	int tmpx = x;
	while(tmpx != 0)
	{
		tmp = tmp*10+tmpx%10;
		tmpx /= 10;
		bit++;
	}
	p[0] = (x/10)*pow(10, bit) + tmp; // odd  bits palindrome
	p[1] = x*pow(10, bit) + tmp;      // even bits palindrome
}
int a, b;
int main()
{
	findPrime(MAXN);
	for(int i = 2; i <= MAXN; i++)
		if(Prime[i])
			PrimeBin[PrimeBinSize++] = i;
	for(int i = 1; i < 9999; i++) // i is half of Palindromes
	{
		int p[2];
		Palindrome(i, p);
		if(isBigPrime(p[0]))
			PalindromePrime[PalindromePrimeSize++] = p[0];
		if(isBigPrime(p[1]))
			PalindromePrime[PalindromePrimeSize++] = p[1];
	}
	//cout << PalindromePrimeSize << endl;
	sort(PalindromePrime, PalindromePrime+PalindromePrimeSize);
	while(cin >> a >> b && !(a==0&&b==0))
	{
		for(int i = 0; PalindromePrime[i] <= b && i < PalindromePrimeSize; i++)
			if(a <= PalindromePrime[i])
				printf("%d\n", PalindromePrime[i]);
	}
	return 0;
}


你可能感兴趣的:(sicily)