湖南工业大学第一届ACM竞赛 我素故我在 DFS

 

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

原文地址:https://www.cnblogs.com/Lyush/p/2047516.html