49 我素故我在
作者:
问题描述 :
有这样一种素数叫纯素数(YY出来的名字),当它是一个多位数的时候,你把它的末位去掉之后余下的数依然是一个素数。比如说2393,2393 本身是一个素数,它的末位去掉之后,余下的是239。239 是一个素数,它的末位去掉之后,余下的是23 。23是一个素数,它的末位去掉之后,余下的是2 。2依然还是一个素数。纯素数的长度叫做“维”。2393 是一个4维素数。3797也是一个4维素数。
输入说明 :
第一行先给出一共有多少组数据N(N<=1000),接下来有N组数据.
每组包括一个整数T(1<=T<=8)。
输出说明 :
按照从小到大的顺序输出所有的T维纯素数。
输入范例 :
3
8
1
4
输出范例 :
23399339
29399999
37337999
59393339
73939133
2
3
5
7
2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393
解题思路:刚开始看见题目有一个暴力枚举的方法,但是自己觉得非常耗时,放弃了。后来仔细一看题目要求时间1s,更加害怕了。(暴力枚举肯定会超时的啊)
又看到深度优先搜索,我突然灵光一现,有了思路。将数的维数看做深度。
接着我又发现,假如说维数是1的话,那么素数只有2,3,5,7这四个数字,也就缩小了计算范围。
然后考虑第n维(n>1),为了满足素数的要求,第n维只能填充1,3,5,7这四个数字。看似题目要求刁钻,实则帮我提高了效率。
然后考虑深度优先搜索的“死胡同”:
1、当前数不是素数
2、当前数的维数已经超出要求
深度优先搜索的出口:
当前数的维数满足要求且当前数是素数
会心一笑,写出代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #include <string.h> 5 #include <ctype.h> 6 7 #define maxn 40 8 9 int rec[maxn] = {2,3,5,7}; 10 int arr[5] = {1,3,5,7,9}; 11 12 int ans[9][20]={0}; //二维数组存放结果 13 int len = 0; 14 void DFS(int nowt,int num); 15 int sushu(int num); 16 int n,t; 17 int main(){ 18 scanf("%d",&n); 19 int i,j; 20 21 for(t=1;t<9;t++){//计算并存放所有可能的结果 22 len = 0; 23 for(j=0;j<4;j++){ 24 DFS(1,rec[j]); 25 } 26 } 27 for(i=0;i<n;i++){ 28 scanf("%d",&t); 29 for(j=0;j<20;j++){ 30 if(ans[t][j]!=0){ 31 printf("%d\n",ans[t][j]);//O(1) 32 }else{ 33 break; 34 } 35 } 36 } 37 return 0; 38 } 39 40 void DFS(int nowt,int num){ 41 if(t==1||nowt == t&&sushu(num)==1){ //t=1是特殊情况,不必判断 42 ans[t][len++] = num; 43 return ; 44 } 45 46 if(nowt>t||sushu(num)==0){ //“死胡同” 47 return ; 48 } 49 50 int i; 51 for(i=0;i<5;i++){ 52 DFS(nowt+1,num*10+arr[i]); 53 } 54 55 } 56 57 int sushu(int num){ 58 int i=0; 59 for(i=3;i*i<=num;i++){ 60 if(num%i==0){ 61 return 0; 62 } 63 } 64 return 1; 65 }