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 }