zoukankan      html  css  js  c++  java
  • poj2251:Dungeon Master

     

    最初没有注意到结果是要求最小的步数,那么就成了最基本的迷宫找到一条出路的问题并记下找到出路时,所花的步数,那么很容易得到代码如下:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 using namespace std;
      5 
      6 #define MAX 1000000
      7 int l,r,c,coun;
      8 char m[30][30][30];
      9 bool flag[30][30][30];
     10 int num[30][30][30]={0};
     11 void work(int i,int j,int level,int mins)
     12 {
     13     //flag[level][i][j] = false;
     14     num[level][i][j] = mins;
     15     if(mins >= coun)
     16         return ;
     17     if(m[level][i][j] == 'E')
     18     {
     19         coun = mins;
     20         return ;
     21     }
     22     
     23     if(level < l-1)
     24     {
     25         if((flag[level+1][i][j] == true) && (num[level+1][i][j] == 0 || mins+1 < num[level+1][i][j]))
     26             work(i,j,level+1,mins+1);
     27     }
     28     if(level > 0)
     29     {
     30         if(flag[level-1][i][j] == true&& (num[level-1][i][j] == 0 || mins+1 < num[level-1][i][j]))
     31             work(i,j,level-1,mins+1);
     32     }
     33     if(i < r-1)
     34     {
     35         if(flag[level][i+1][j] == true&& (num[level][i+1][j] == 0 || mins+1 < num[level][i+1][j]))
     36             work(i+1,j,level,mins+1);
     37     }
     38     if(i > 0)
     39     {
     40         if(flag[level][i-1][j] == true&& (num[level][i-1][j] == 0 || mins+1 < num[level][i-1][j]))
     41             work(i-1,j,level,mins+1);
     42     }
     43     if(j < c-1)
     44     {
     45         if(flag[level][i][j+1] == true&& (num[level][i][j+1] == 0 || mins+1 < num[level][i][j+1]))
     46             work(i,j+1,level,mins+1);
     47     }
     48     if(j > 0)
     49     {
     50         if(flag[level][i][j-1] == true&& (num[level][i][j-1] == 0 || mins+1 < num[level][i][j-1]))
     51             work(i,j-1,level,mins+1);
     52     }
     53 }
     54 
     55 int main()
     56 {
     57     while(cin>>l>>r>>c)
     58     {
     59         if(l == 0 && r == 0 && c == 0)
     60             break;
     61         int startl,starti,startj;
     62         char s;
     63         scanf("%c",&s);
     64         for(int i = 0; i < l; i++ )
     65         {
     66             for(int j = 0; j < r; j++)
     67             {
     68                 for(int k = 0; k < c; k++)
     69                 {
     70                     scanf("%c",&m[i][j][k]);
     71                     if(m[i][j][k] == 'S')
     72                     {
     73                         startl = i;
     74                         starti = j;
     75                         startj = k;
     76                     }
     77                     if(m[i][j][k] == '#')
     78                         flag[i][j][k] = false;
     79                     else
     80                         flag[i][j][k] = true;
     81                 }
     82                 scanf("%c",&s);
     83             }
     84             scanf("%c",&s);
     85         }
     86         /*for(int i = 0; i < l; i++ )
     87          {
     88          for(int j = 0; j < r; j++)
     89          {
     90          for(int k = 0; k < c; k++)
     91          {
     92          printf("%c",m[i][j][k]);
     93          }
     94          printf("
    ");
     95          }
     96          printf("
    ");
     97          }*/
     98         coun = MAX;
     99         memset(num,0,sizeof(num));
    100         work(starti,startj,startl,0);
    101         if(coun < MAX)
    102             printf("Escaped in %d minute(s).
    ", coun);
    103         else
    104             printf("Trapped!
    ");
    105     }
    106     return 0;
    107 }
    View Code

    注意到之后,那么bool 属性的flag其实就不必了,我在下文代码中的flag其实只是用来判断那个点是否是‘#’字符而已,没什么用,必须遍历所有情况才能够找出最小步数,那么就只需要剪枝就好了。

    最开始,我注意到的剪枝方法就是最简单的,只有一个返回条件:

    1.当前的步数已经超过最小的通过迷宫的步数的时候,返回。

    结果发现无限循环了。。。想了一想,因为并没有限制重复的搜索,所以一直在无限制的重复搜索下去了。

    那么加上第二个剪枝条件来防止无限制地重复搜索:

    2.当下一步要访问的点之前已经访问过的时候,而且如果要访问的话,之前访问到该点的步数小于或者等于当前情况访问到该点的步数,则不再去访问。

    按照这个思路,写完代码提交过后,又出现了超时。。。

    则加上第三个剪枝条件,实质上是加强了第一个条件:

    当前访问到的点已经经过的步数加上到达出口所需的最短步数已经超过 之前计算出的通过迷宫所需的最短步数时,则返回。

    终于AC了!现在献上AC代码

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <math.h>
      5 #include <stdlib.h>
      6 using namespace std;
      7 
      8 #define MAX 1000000
      9 int l,r,c,coun;
     10 char m[30][30][30];
     11 bool flag[30][30][30];
     12 int num[30][30][30]={0};
     13 int startl,starti,startj,endle,endi,endj;
     14 void work(int i,int j,int level,int mins)
     15 {
     16     //flag[level][i][j] = false;
     17     num[level][i][j] = mins;
     18     if(mins+abs(i-endi)+abs(j-endj)+abs(level-endle) >= coun)
     19         return ;
     20     if(m[level][i][j] == 'E')
     21     {
     22         coun = mins;
     23         return ;
     24     }
     25     
     26     if(level < l-1)
     27     {
     28         if((flag[level+1][i][j] == true) && (num[level+1][i][j] == 0 || mins+1 < num[level+1][i][j]))
     29             work(i,j,level+1,mins+1);
     30     }
     31     if(level > 0)
     32     {
     33         if(flag[level-1][i][j] == true&& (num[level-1][i][j] == 0 || mins+1 < num[level-1][i][j]))
     34             work(i,j,level-1,mins+1);
     35     }
     36     if(i < r-1)
     37     {
     38         if(flag[level][i+1][j] == true&& (num[level][i+1][j] == 0 || mins+1 < num[level][i+1][j]))
     39             work(i+1,j,level,mins+1);
     40     }
     41     if(i > 0)
     42     {
     43         if(flag[level][i-1][j] == true&& (num[level][i-1][j] == 0 || mins+1 < num[level][i-1][j]))
     44             work(i-1,j,level,mins+1);
     45     }
     46     if(j < c-1)
     47     {
     48         if(flag[level][i][j+1] == true&& (num[level][i][j+1] == 0 || mins+1 < num[level][i][j+1]))
     49             work(i,j+1,level,mins+1);
     50     }
     51     if(j > 0)
     52     {
     53         if(flag[level][i][j-1] == true&& (num[level][i][j-1] == 0 || mins+1 < num[level][i][j-1]))
     54             work(i,j-1,level,mins+1);
     55     }
     56 }
     57 
     58 int main()
     59 {
     60     while(cin>>l>>r>>c)
     61     {
     62         if(l == 0 && r == 0 && c == 0)
     63             break;
     64         
     65         char s;
     66         scanf("%c",&s);
     67         for(int i = 0; i < l; i++ )
     68         {
     69             for(int j = 0; j < r; j++)
     70             {
     71                 for(int k = 0; k < c; k++)
     72                 {
     73                     scanf("%c",&m[i][j][k]);
     74                     if(m[i][j][k] == 'S')
     75                     {
     76                         startl = i;
     77                         starti = j;
     78                         startj = k;
     79                     }
     80                     if(m[i][j][k] == 'E')
     81                     {
     82                         endle = i;
     83                         endi = j;
     84                         endj = k;
     85                     }
     86                     if(m[i][j][k] == '#')
     87                         flag[i][j][k] = false;
     88                     else
     89                         flag[i][j][k] = true;
     90                 }
     91                 scanf("%c",&s);
     92             }
     93             scanf("%c",&s);
     94         }
     95         /*for(int i = 0; i < l; i++ )
     96          {
     97          for(int j = 0; j < r; j++)
     98          {
     99          for(int k = 0; k < c; k++)
    100          {
    101          printf("%c",m[i][j][k]);
    102          }
    103          printf("
    ");
    104          }
    105          printf("
    ");
    106          }*/
    107         coun = MAX;
    108         memset(num,0,sizeof(num));
    109         work(starti,startj,startl,0);
    110         if(coun < MAX)
    111             printf("Escaped in %d minute(s).
    ", coun);
    112         else
    113             printf("Trapped!
    ");
    114     }
    115     return 0;
    116 }
    View Code
  • 相关阅读:
    springboot 时间戳和 数据库时间相差14个小时
    财富的起源读书笔记1
    高性能mysql读书笔记1
    springboot项目使用 apollo 配置中心
    MongoDB图形化管理工具
    oracle体系结构详解
    三、oracle 体系结构
    用DOS批处理实现FTP自动上传、下载、清理文件
    ORA-01033:ORACLE initialization or shutdown in progress
    从WEB SERVICE 上返回大数据量的DATASET
  • 原文地址:https://www.cnblogs.com/xiaoshen555/p/3816385.html
Copyright © 2011-2022 走看看