我素故我在
时间限制(普通/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;
}