zoukankan      html  css  js  c++  java
  • 湖南工业大学第一届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;
    }
    

  • 相关阅读:
    F#学习开篇(一)
    F#学习(二)
    认识“闭包”
    Silverlight显示控件换行的几种方式
    关于P问题、NP问题、NPC问题
    LINQ&EF任我行(二)LinQ to Object
    WPF中资源的引用方法
    Linq to EF 与Linq to Object 使用心得
    C#中如何用拼音模糊匹配汉字的首字母
    WPF获取应用程序路径方法,获取程序运行路径方法
  • 原文地址:https://www.cnblogs.com/Lyush/p/2047516.html
Copyright © 2011-2022 走看看