问题链接:POJ NOI0113-11 回文素数。
-
总时间限制:
- 5000ms 内存限制:
- 65536kB
-
描述
- 一个数如果从左往右读和从右往左读数字是相同的,则称这个数是回文数,如121,1221,15651都是回文数。给定位数n,找出所有既是回文数又是素数的n位十进制数。(注:不考虑超过整型数范围的情况)。 输入
- 位数n,其中1<=n<=9。 输出
-
第一行输出满足条件的素数个数。
第二行按照从小到大的顺序输出所有满足条件的素数,两个数之间用一个空格区分。
样例输入
-
1
样例输出
-
4 2 3 5 7
问题链接:Bailian3247 回文素数
问题分析:
既要判定一个数是不是回文,又要判定这个数是不是素数。然而用判定的方法判定一个数是否是回文是比较慢的,如果数的个数巨大,那必然TLE。
程序说明:
判定素数是套路,然而生成回文数的逻辑要难懂许多。
题记:
如果能找到一种生成的方法,一般要比枚举判定要快许多。
参考链接:HDU1431 素数回文
AC的C语言程序如下:
/* Bailian3247 回文素数 */
#include <stdio.h>
#include <math.h>
#define TRUE 1
#define FALSE 0
#define N 40000
int isnotprime[N + 1] = {0};
int prime[N] = {0}, pcount;
void setprime(int n)
{
int i, j;
pcount = 0;
prime[pcount++] = 2;
for(i=3; i<=n; i+=2)
if(isnotprime[i] == FALSE) {
prime[pcount++] = i;
for(j=i*i; j<=n; j+=2*i)
isnotprime[j] = TRUE;
}
}
int isPrime(int n, int prime[])
{
int i = 0, m = sqrt(n);
while(prime[i] <= m) {
if(n % prime[i] == 0)
return FALSE;
i++;
}
return TRUE;
}
int main()
{
int n, i;
int digits[10] = {1};
int ans[6000], acount=0;
setprime(N);
scanf("%d", &n);
digits[n - 1] = 1;
if(n == 1)
digits[n - 1]++;
while(!digits[n]) {
int a = 0, b = n / 2;
for(i=0; i<b; i++)
digits[i] = digits[n - i - 1];
for(i=0; i<n; i++) {
a *= 10;
a += digits[i];
}
if(isPrime(a, prime))
ans[acount++] = a;
digits[b]++;
while(b < n) {
if(digits[b] > 9) {
digits[b + 1]++;
digits[b] -= 10;
}
b++;
}
}
printf("%d\n", acount);
for(i=0; i<acount; i++)
printf("%d ", ans[i]);
printf("\n");
return 0;
}
TLE的C语言程序如下:
/* Bailian3247 回文素数 */
#include <stdio.h>
#include <time.h>
/*#define DEBUG*/
#define BASE 10
#define TRUE 1
#define FALSE 0
int ans[8000];
int count;
// 函数功能:判断n是否为回文数
// 参数n:需要判断是否为回文数的数
int isPalindrome(int n)
{
int temp1 = n, temp2 = 0;
while(n > 0) {
temp2 = temp2 * 10 + n % 10;
n /= 10;
}
return temp1 == temp2;
}
int isPrime(int n)
{
int i;
if(n % 2) {
/* 奇数 */
if(n == 1)
return FALSE;
for(i=3; i*i<=n; i+=2) {
if(n % i == 0)
return FALSE;
}
} else {
/* 偶数 */
return n == 2 ? TRUE : FALSE;
}
return TRUE;
}
int main(void)
{
#ifdef DEBUG
clock_t starttime, finishtime;
double totaltime;
starttime = clock();
#endif
int n, start, end, i;
scanf("%d", &n);
start = 1;
for(i=1; i<n; i++)
start *= BASE;
end = start * BASE - 1;
count = 0;
for(i=start; i<= end; i++)
if(isPalindrome(i) && isPrime(i))
ans[count++] = i;
printf("%d\n", count);
for(i=0; i<count; i++) {
if(i)
printf(" ");
printf("%d", ans[i]);
}
printf("\n");
#ifdef DEBUG
finishtime = clock();
totaltime = (double)(finishtime - starttime) / CLOCKS_PER_SEC;
printf("App elapsed: %fs\n\n", totaltime);
#endif
return 0;
}