我素故我在
时间限制(普通/Java):1000MS/3000MS 运行内存限制:65536KByte
总提交:17 测试通过:9
描述
有这样一种素数叫纯素数(YY出来的名字),当它是一个多位数的时候,你把它的末位去掉之后余下的数依然是一个素数。比如说2393,2393 本身是一个素数,它的末位去掉之后,余下的是239。239 是一个素数,它的末位去掉之后,余下的是23 。23是一个素数,它的末位去掉之后,余下的是2 。2依然还是一个素数。纯素数的长度叫做“维”。2393 是一个4维素数。3797也是一个4维素数。
输入
输出
按照从小到大的顺序输出所有的T维纯素数。
样例输入
1
1
样例输出
2
3
5
7
这次校赛得一个很有意思的一题,比赛完之后的解题报告中得知用DFS做的这道题,而比赛中我却始终想用循环写出这道题目......到底是道行不够深啊,没有掌握DFS的根本属性,本题中有一个关键的条件,而这个条件就是决定了这道题目用DFS做是最契合题意的,这句话就是“当它是一个多位数的时候,你把它的末位去掉之后余下的数依然是一个素数” 这说明了后面的判断是和前一次的判断是有联系的。再者,我们可以预想到 四位数 的纯素数 肯定和 三位数 、五位数 的 纯素数有关系,因此,一次DFS能够算出你想要的所有值,由于这里N的取值可能很大,所以在改进了一下下,DFS+打表,即在询问之前,将所有的对应的纯素数均计算出来,并用数组存储好,这样的后面的询问便可很快的输出来。
代码如下:
代码如下:
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> #include<time.h> // 由于N 的取值可以很大,所以打表过,即首先 // 算出 1- 8 的所有纯素数的的值,存起来,以后每次询问时 // 便直接打印就行。 // 但虽说如此,用管理员号看了下测试数据,很水,N=8..... int num[10][100],N; // num用来存储纯素数 int l[10]; // 用来存储对应位数限制的纯素数的个数 bool isp(int x) // 模板化的判断素数函数 { if( x<=1 ) return 0; if( x==2 ) return 1; int lim = ( int ) sqrt( x ) ; for(int i = 2; i <= lim; ++i) if( !( x % i ) ) return false; return true; } void DFS( int x, int len,int cnt) { if(len>8) return ; num[len][cnt]=x; // 由于进来后是无条件的存储该值 for(int i=1;i<10;++i) //所以必须保证传入的参数质量达标 { if(isp(10*x+i)) // 保证传入的均为纯素数 DFS(10*x+i,len+1,++l[len+1]); } } int main() { for(int i=2;i<10;++i) { if(isp(i)) // 与DFS中作用一样 DFS(i,1,++l[1]);// 刚开始把第三个参数赋值为 1,结果ask=1时 } // 无结果,后来知道是那样 l[1] 根本没有赋值 scanf("%d",&N); while(N--) { int ask; scanf("%d",&ask); for(int i=1;i<=l[ask];++i) //注意从 1开始 因为参数传的是 ++l[x] printf("%d\n",num[ask][i]); } return 0; }