迷宫寻宝(一)
时间限制:
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
-
输入可能会有多组测试数据(不超过10组)。
最可悲的事情莫过于写了一晚上 连超时的资格都没有 一直 wa
始终不对 明天再解决吧
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dir[][2]={{0,-1},{-1,0},{0,1},{1,0}}; //方向
bool f[1001][1001]; //标记
char a[1001][1001];
int d[10],c[10]; //记录 钥匙的数量
int m,n;
bool i=0;
void Dfs(int x,int y){
if(i) return ;
if(a[x][y]=='G'){
i=1;
return ;
}
else{
int x1=x,y1=y;
for(int j=0;j<4;j++){
x=x1+dir[j][0];
y=y1+dir[j][1];
if(x<0||y<0) continue;
if(x>m||y>n) continue;
if(a[x][y]!='X'){
if(!f[x][y]&&a[x][y]=='.'||a[x][y]=='G'){
f[x][y]=1;
Dfs(x,y);
f[x][y]=0;
}
else if(a[x][y]>='A'&&a[x][y]<='E'&&!f[x][y]){
if(d[a[x][y]-'A']==c[a[x][y]-'A']){ //如果相等的话就继续
//cout<<a[x][y]<<" "<<d[a[x][y]-'A']<<endl;
f[x][y]=1;
Dfs(x,y);
f[x][y]=0;
}
}
}
}
return ;
}
}
void DFS(int x,int y,int *d){
//cout<<x<<" "<<y<<endl;
if(i) return ;
if(a[x][y]=='G'){
i=1;
return ;
}
else{
int x1=x,y1=y;
for(int j=0;j<4;j++){
x=x1+dir[j][0];
y=y1+dir[j][1];
if(x<0||y<0) continue;
if(x>m||y>n) continue;
if(a[x][y]!='X'){
if(!f[x][y]&&a[x][y]=='.'||a[x][y]=='G'){
f[x][y]=1;
DFS(x,y,d);
f[x][y]=0;
}
else if(a[x][y]>='a'&&a[x][y]<='e'&&!f[x][y]){
d[a[x][y]-'a']++; //记录钥匙数量
//cout<<d[a[x][y]-'a']<<" "<<a[x][y]<<endl;
a[x][y]='.';
f[x][y]=1;
DFS(x,y,d);
f[x][y]=0;
}
else if(a[x][y]>='A'&&a[x][y]<='E'&&!f[x][y]){
if(d[a[x][y]-'A']==c[a[x][y]-'A']){ //如果相等的话就继续
//cout<<a[x][y]<<" "<<d[a[x][y]-'A']<<endl;
f[x][y]=1;
DFS(x,y,d);
f[x][y]=0;
}
}
}
}
return ;
}
}
int main(){
int x,y;
while(cin>>m>>n&&m&&n){
memset(c,0,sizeof(c));
memset(f,0,sizeof(f));
memset(d,0,sizeof(d));
memset(a,'0',sizeof(a));
for(int j=0;j<m;j++){
for(int k=0;k<n;k++){
cin>>a[j][k];
if(a[j][k]=='S'){
x=j; y=k;
}
if(a[j][k]>='a'&&a[j][k]<='e'){
c[a[j][k]-'a']++; //记录所有钥匙的数量
}
}
}
i=0;
for(int j=0;j<5;j++){ //如果没钥匙的话 标记为 -1
if(!c[j]) c[j]=-1;
}
//cout<<endl;
f[x][y]=1;
DFS(x,y,d);
if(!i)
Dfs(x,y);
if(i){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}