Luogu p1217 [USACO1.5]回文质数 Prime Palindromes

题目描述

因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。

写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)( 一亿)间的所有回文质数;

输入输出格式

输入格式:

第 1 行: 二个整数 a 和 b .

 

输出格式:

输出一个回文质数的列表,一行一个。

输入输出样例

输入样例#1:
5 500
 
输出样例#1: 
5
7
11
101
131
151
181
191
313
353
373
383

说明

Hint 1: Generate the palindromes and see if they are prime.

提示 1: 找出所有的回文数再判断它们是不是质数(素数).

Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.

提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。

 

思路:

首先很容易想到直接循环检测是否是回文数和质数必然超时,显然我们只能构造一种,然后判断是否是另一种。质数显然无法构造,我们通过循环构造回文数,然后判断是否为质数,解决本题。

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #include <stdlib.h>
 5 
 6 int isPrime(long);
 7 char *makePalindrome(char *);
 8 char *makePalindrome2(char *);
 9 void check(char *);
10 int cmp(const void *,const void *);
11 
12 int num[800],cnt;
13 
14 long a,b;
15 
16 int main() {
17     int i;
18     char s[20];
19     char *s2;
20     cnt=0;
21     scanf ("%ld%ld",&a,&b);
22     for (i=1;i<10000;i++) {
23         sprintf (s,"%d",i);
24         s2=makePalindrome(s);
25         check(s2);
26         s2=makePalindrome2(s);
27         check(s2);
28     }
29     qsort (num,cnt,sizeof(int),cmp);
30     for (i=0;i<cnt;i++) {
31         printf ("%d\n",num[i]);
32     }
33     return 0;
34 }
35 
36 int isPrime(long k) {
37     long sqr=sqrt(k);
38     int i;
39     for (i=2;i<=sqr;i++) {
40         if (!(k%i)) return 0;
41     }
42     return 1;
43 }
44 
45 char *makePalindrome(char *s) {  /* 构造abccba型回文数 */
46     int i;
47     int len=strlen(s);
48     int newlen=len*2;
49     char *news=(char *)malloc(sizeof(char)*(newlen+1));
50     strcpy(news,s);
51     for (i=0;i<len;i++) {
52         news[newlen-i-1]=news[i];
53     }
54     news[newlen]='\0';
55     return news;
56 }
57 
58 char *makePalindrome2(char *s) {  /* 构造abcba型回文数 */
59     int i;
60     int len=strlen(s);
61     int newlen=len*2-1;
62     char *news=(char *)malloc(sizeof(char)*(newlen+1));
63     strcpy(news,s);
64     for (i=0;i<len;i++) {
65         news[newlen-i-1]=news[i];
66     }
67     news[newlen]='\0';
68     return news;
69 }
70 
71 void check(char *s) {
72     long n,k;
73     int length,i;
74     length=strlen(s);
75     n=0;k=1;
76     for (i=length-1;i>=0;i--) {
77         n+=k*(s[i]-'0');
78         k*=10;
79     }
80     if (n<a || n>b) return;
81     if (isPrime(n)) {
82         num[cnt++]=n;
83     }
84 }
85 
86 int cmp(const void *a,const void *b) {  
87     return (*(int *)a-*(int *)b);
88 }

 

posted @ 2018-03-29 17:42  yachen2018  阅读(133)  评论(0编辑  收藏  举报