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
  • 相关阅读:
    scoped中预处理器的解析问题
    uni-app中IOS离线打包报HBuilder has conflicting provisioning settings
    js 四则运算
    Chrome 的更改可能会破坏您的应用:为同网站 Cookie 更新做好准备
    银行数据仓库体系实践(20)--浅谈银行数据仓库发展趋势
    数据仓库十大主题;TeraData金融数据模型
    Linux环境下SVN的安装,创建用户以及对应用户的权限设置
    银行数据仓库体系实践(19)--数据应用之AI
    from flask.ext.wtf import Form提示No module named 'flask.ext'
    flask学习笔记2 路由
  • 原文地址:https://www.cnblogs.com/xiaoshen555/p/3816385.html
Copyright © 2011-2022 走看看