标签:
一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。
4 4 S.X. a.X. ..XG .... 3 4 S.Xa .aXB b.AG 0 0
YES NO
其实就是一道搜索题 卡了我一天多 不过还是挺喜欢这道题的
其实广搜 深搜都能做 。在这里我是用深搜做的
主要就是判断遇到门的时候怎么办 。如果遇到门 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; }
标签:
原文地址:http://blog.csdn.net/su20145104009/article/details/51000942