nyoj82 迷宫寻宝(DFS 推荐看看)
Posted 甄情
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nyoj82 迷宫寻宝(DFS 推荐看看)相关的知识,希望对你有一定的参考价值。
迷宫寻宝(一)
时间限制:1000 ms | 内存限制:65535 KB
难度:4
- 描述
-
一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。
- 输入
- 输入可能会有多组测试数据(不超过10组)。
每组测试数据的第一行包含了两个整数M,N(1<N,M<20),分别代表了迷宫的行和列。接下来的M每行有N个字符,描述了迷宫的布局。其中每个字符的含义如下:
.表示可以走的路
S:表示ACM的出发点
G表示宝藏的位置
X表示这里有墙,ACM无法进入或者穿过。
A,B,C,D,E表示这里是门,a,b,c,d,e表示对应大写字母的门上的钥匙。
注意ACM只能在迷宫里向上下左右四个方向移动。
最后,输入0 0表示输入结束。 - 输出
- 每行输出一个YES表示ACM能找到宝藏,输出NO表示ACM找不到宝藏。
- 样例输入
-
4 4 S.X. a.X. ..XG .... 3 4 S.Xa .aXB b.AG 0 0
- 样例输出
-
YES NO
- 来源
- POJ月赛改编
- 上传者
- 张云聪
其实就是一道搜索题 卡了我一天多 不过还是挺喜欢这道题的
其实广搜 深搜都能做 。在这里我是用深搜做的
主要就是判断遇到门的时候怎么办 。如果遇到门 1.当前的钥匙不足以开门 2.当前的钥匙可以开门
第二种就不用说了 。主要说说第一种情况 。如果当前的钥匙不足以开门 我们需要在地图其它的可行区域找全 是否能够找到剩余的钥匙 然后再回到门前
,对于如何回到门前呢?我们可以定义一个数组来存贮门的位置 当其它区域全部找全后我们再回到门前判断能不能开门即可
#include <stdio.h> #include <string.h> #include <queue> using namespace std; //地图 char map[25][25]; //遍历标记 bool vis[25][25]; //是否找到宝藏 bool result; //钥匙总数 int key[5]; //当前找到的钥匙总数 int curKey[5]; int n,m; int st_x,st_y; struct node { int x,y; bool exit; }door[5]; void check(); void dfs(int x,int y) { if(x<0||y<0||x>=m||y>=n||map[x][y]=='X'||vis[x][y]) return ; //遇到门 判断能不能开门 如果不能开门 入栈 if(map[x][y]>='A'&&map[x][y]<='E'&&curKey[map[x][y]-'A']<key[map[x][y]-'A']) { door[map[x][y]-'A'].x=x; door[map[x][y]-'A'].y=y; door[map[x][y]-'A'].exit=true; return ; } vis[x][y]=true; //找到一个钥匙 curkey[]+1 if(map[x][y]>='a'&&map[x][y]<='e') curKey[map[x][y]-'a']++; if(map[x][y]=='G') { result=true; return ; } dfs(x+1,y); dfs(x-1,y); dfs(x,y+1); dfs(x,y-1); check(); } //地图找完后 回到门前再次判断是否可以开门 void check() { for(int i=0;i<5;i++) { if(door[i].exit) { if(curKey[i]==key[i]) { int x=door[i].x; int y=door[i].y; dfs(x+1,y); dfs(x-1,y); dfs(x,y+1); dfs(x,y-1); } } } } int main() { while(~scanf("%d %d",&m,&n)) { if(m==0&&n==0) break; memset(key,0,sizeof(key)); memset(map,0,sizeof(map)); memset(vis,false,sizeof(vis)); memset(&door,0,sizeof(&door)); memset(curKey,0,sizeof(curKey)); for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { char ch; scanf(" %c",&ch); map[i][j]=ch; if(ch>='a'&&ch<='e') key[ch-'a']++; if(ch=='S') st_x=i,st_y=j; } } result=false; dfs(st_x,st_y); if(result) printf("YES\n"); else printf("NO\n"); } return 0; }
以上是关于nyoj82 迷宫寻宝(DFS 推荐看看)的主要内容,如果未能解决你的问题,请参考以下文章