洛谷 p1217 回文质数
题目描述
因为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
思路
旭晨大神推的题,提示不能看题目本身的说明,看了基本就告诉答案了233.
这题本身其实没有特别大的难度,判断质数和回文数都是比较基础的问题,难点在于此题的所给的数的范围(1~100000000),如果是一个一个循环查找的话必定有一个大的范围会超时。
思考良久无果,觉得可能不是单纯的模拟(小白只会模拟),然后大神告诉我这题就是模拟。最终还是放弃了。看了说明之后顿悟。
先找出所有的回文数,再对找出的回文数进行判断是否为质数,若是,则输出。
代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #define MAX 100 5 int judgedigit(int num); 6 int judge(int num); 7 int judgePalindrome(int num); 8 void printf1(int m,int n); 9 void printf2(int m,int n); 10 void printf3(int m,int n); 11 void printf4(int m,int n); 12 void printf5(int m,int n); 13 void printf6(int m,int n); 14 void printf7(int m,int n); 15 void printf8(int m,int n); 16 int main() 17 { 18 int m,n; 19 int adigit,bdigit; 20 scanf("%d %d",&m,&n); 21 adigit=judgedigit(n); 22 bdigit=judgedigit(m); 23 if(adigit>=1&&bdigit<=1)printf1(m,n); 24 if(adigit>=2&&bdigit<=2)printf2(m,n); 25 if(adigit>=3&&bdigit<=3)printf3(m,n); 26 if(adigit>=4&&bdigit<=4)printf4(m,n); 27 if(adigit>=5&&bdigit<=5)printf5(m,n); 28 if(adigit>=6&&bdigit<=6)printf6(m,n); 29 if(adigit>=7&&bdigit<=7)printf7(m,n); 30 if(adigit>=8&&bdigit<=8)printf8(m,n); 31 return 0; 32 } 33 34 int judge(int num){ 35 int i; 36 for(i=2;i<=sqrt(num);i++){ 37 if(num%i==0){ 38 return 0; 39 } 40 } 41 return 1; 42 } 43 44 int judgedigit(int num){ 45 int temp=0; 46 while(num>0){ 47 num/=10; 48 temp++; 49 } 50 return temp; 51 } 52 53 int judgePalindrome(int num){ 54 int numt=num; 55 int temp=0; 56 while(numt>0){ 57 temp=temp*10+numt%10; 58 numt/=10; 59 } 60 if(temp==num) return 1; 61 else return 0; 62 } 63 64 void printf1(int m,int n){ 65 int d1; 66 for(d1=m;d1<=10;d1++){/*1位数*/ 67 int palindrome=d1; 68 if(judge(palindrome)==1){ 69 printf("%d\n",palindrome); 70 } 71 } 72 } 73 void printf2(int m,int n){ 74 if(m<=11&&n>=11) 75 printf("%d\n",11); 76 } 77 void printf3(int m,int n){ 78 int d1,d2; 79 for(d1=1;d1<=9;d1+=2){/*3位数*/ 80 for(d2=0;d2<10;d2++){ 81 int palindrome=d1*100+d2*10+d1; 82 if(palindrome>=m&&palindrome<=n){ 83 if(judge(palindrome)==1){ 84 printf("%d\n",palindrome); 85 } 86 } 87 } 88 } 89 } 90 void printf4(int m,int n){ 91 int d1,d2; 92 for(d1=1;d1<=9;d1+=2){/*4位数*/ 93 for(d2=0;d2<10;d2++){ 94 int palindrome=d1*1000+d2*100+d2*10+d1; 95 if(palindrome>=m&&palindrome<=n){ 96 if(judge(palindrome)==1){ 97 printf("%d\n",palindrome); 98 } 99 } 100 } 101 } 102 } 103 void printf5(int m,int n){ 104 int d1,d2,d3; 105 for(d1=1;d1<=9;d1+=2){/*5位数*/ 106 for(d2=0;d2<10;d2++){ 107 for(d3=0;d3<10;d3++){ 108 int palindrome=d1*10000+d2*1000+d3*100+d2*10+d1; 109 if(palindrome>=m&&palindrome<=n){ 110 if(judge(palindrome)==1){ 111 printf("%d\n",palindrome); 112 } 113 } 114 } 115 } 116 } 117 } 118 void printf6(int m,int n){ 119 int d1,d2,d3; 120 for(d1=1;d1<=9;d1+=2){/*6位数*/ 121 for(d2=0;d2<10;d2++){ 122 for(d3=0;d3<10;d3++){ 123 int palindrome=d1*100000+d2*10000+d3*1000+d3*100+d2*10+d1; 124 if(palindrome>=m&&palindrome<=n){ 125 if(judge(palindrome)==1){ 126 printf("%d\n",palindrome); 127 } 128 } 129 } 130 } 131 } 132 } 133 void printf7(int m,int n){ 134 int d1,d2,d3,d4; 135 for(d1=1;d1<=9;d1+=2){/*7位数*/ 136 for(d2=0;d2<10;d2++){ 137 for(d3=0;d3<10;d3++){ 138 for(d4=0;d4<10;d4++){ 139 int palindrome=d1*1000000+d2*100000+d3*10000+d4*1000+d3*100+d2*10+d1; 140 if(palindrome>=m&&palindrome<=n){ 141 if(judge(palindrome)==1){ 142 printf("%d\n",palindrome); 143 } 144 } 145 } 146 } 147 } 148 } 149 } 150 void printf8(int m,int n){ 151 int d1,d2,d3,d4; 152 for(d1=1;d1<=9;d1+=2){/*8位数*/ 153 for(d2=0;d2<10;d2++){ 154 for(d3=0;d3<10;d3++){ 155 for(d4=0;d4<10;d4++){ 156 int palindrome=d1*10000000+d2*1000000+d3*100000+d4*10000+d4*1000+d3*100+d2*10+d1; 157 if(palindrome>=m&&palindrome<=n){ 158 if(judge(palindrome)==1){ 159 printf("%d\n",palindrome); 160 } 161 } 162 } 163 } 164 } 165 } 166 }
后记
上网查询之后得知,对于偶数位的回文质数只有11,不存在其他的数字。对于整数11,有一个奇特的性质,即11的所有整数倍的数字,其奇数位上数字之和等于偶数位上的数字之和。而对于偶数位的回文数,其所有数字是关于中心对称的,也即其奇数位上数字之和等于偶数位上的数字之和。故除11之外的所有偶数位回文数都可以被11整除。代码可以把此部分去除。
附上质数和回文数的判断函数
1 int judgepalindrome(int num){ 2 int temp=num,a=0; 3 while(temp>0){ 4 a=a*10+temp%10; 5 temp/=10; 6 } 7 if(a==num)return 1; 8 else return 0; 9 }
1 int judgeprime(int num){ 2 int i; 3 for(i=0;i<=sort(num);i++){ 4 if(num%i==0) return 0; 5 } 6 return 1; 7 }