迷宫寻宝(一)
时间限制: 1 Sec 内存限制: 64 MB提交: 24 解决: 7
[ 提交][ 状态][ 讨论版]
题目描述
一个叫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表示输入结束。
每组测试数据的第一行包含了两个整数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
# include<stdio.h> # include<queue> # include<string.h> using namespace std; int b[4][2]={0,1,1,0,-1,0,0,-1};//上下左右四个方向 char a1[25][25]; int v[25][25];//标记走过的路 int n,m,k1[6],k2[6],s1,s2,k; struct node{ int x,y; }; int dfs() { k=0; memset(v,0,sizeof(v)); queue<node>s; node p,q; p.x=s1; p.y=s2; s.push(p); v[s1][s2]=1; while(!s.empty()) { p=s.front(); s.pop(); if(a1[p.x][p.y]=='G')//如果找到宝箱 return 1; for(int i=0;i<4;i++) { q.x=p.x+b[i][0]; q.y=p.y+b[i][1]; if(q.x>=0&&q.x<n&&q.y>=0&&q.y<m&&a1[q.x][q.y]>='a'&&a1[q.x][q.y]<='e') { k2[a1[q.x][q.y]-'a']++; a1[q.x][q.y]='.'; k=1;//找到钥匙 } if(q.x>=0&&q.x<n&&q.y>=0&&q.y<m&&!v[q.x][q.y]&&a1[q.x][q.y]!='X') { if(a1[q.x][q.y]>='A'&&a1[q.x][q.y]<='E') { if(k2[a1[q.x][q.y]-'A']==k1[a1[q.x][q.y]-'A'])//找到的钥匙数与总共的钥匙数的关系 { //如果相等这开门; s.push(q); v[q.x][q.y]=1; } } else { s.push(q); v[q.x][q.y]=1; } } } } if(!k) return -1; //如果没找到钥匙 else return 0; //找到钥匙但没找到宝箱 } int main(){ while(~scanf("%d%d",&n,&m)&&m&&n) { getchar(); int i,j; memset(k1,0,sizeof(k1)); memset(k2,0,sizeof(k2)); for(i=0;i<n;i++) { scanf("%s",&a1[i]); for(j=0;j<m;j++) if(a1[i][j]>='a'&&a1[i][j]<='e') k1[a1[i][j]-'a']++; else if(a1[i][j]=='S'){ s1=i;s2=j; } getchar(); } while(1)//每次都重新调用函数 { int w=dfs(); if(w==1) { //如果返回值为1 说明已经找到宝箱 printf("YES\n"); break; } else if(w==-1) // 如果没有找到钥匙并且没有找到 宝箱 则说明不可能成功 { printf("NO\n");break; } } } return 0; }