迷宫寻宝(一)
时间限制: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
题解:
先遍历能走的,找到能找到的钥匙(不需要回溯)
然后对每个门判断是否有并且钥匙是否都找到,然后以门的坐标为起点进行dfs即可。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define inf 0x3f3f3f3f
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&(-x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max(a,b) a>b?a:b
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-9;
const int maxn = 22;
const int maxm = 10000005;
using namespace std;
inline int read(){
int x(0),f(1);
char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct{
bool isHave;
int x,y;
}door[5];
int key[5];
int findKey[5];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m,flag;
int si,sj,di,dj;
char mp[21][21];
bool vis[21][21];
void dfs2();
void dfs1(int si,int sj){
if(si>=n||si<0||sj>=m||sj<0||mp[si][sj]=='X'||vis[si][sj]){
return;
}
if(si==di&&sj==dj){
flag=1;
}
if(flag){
return;
}
if(islower(mp[si][sj])){
++findKey[mp[si][sj]-'a'];
}
if(mp[si][sj]>='A'&&mp[si][sj]<='E'&&door[mp[si][sj]-'A'].isHave==false){
door[mp[si][sj]-'A'].x=si;
door[mp[si][sj]-'A'].y=sj;
door[mp[si][sj]-'A'].isHave=true;
return;
}
vis[si][sj]=true;
for(int i=0;i<4;++i){
dfs1(si+dx[i],sj+dy[i]);
}
dfs2();
}
void dfs2(){
for(int i=0;i<5;++i){
if(findKey[i]==key[i]&&door[i].isHave){
dfs1(door[i].x,door[i].y);
}
}
}
int main(){
char str[22];
while(~scanf("%d%d",&n,&m),n,m){
flag=0;
mes(door,false);
mes(vis,false);
mes(key,0);
mes(findKey,0);
for(int i=0;i<n;++i){
scanf("%s",str);
for(int j=0;j<m;++j){
mp[i][j]=str[j];
if(str[j]=='S'){
si=i,sj=j;
}else if(str[j]=='G'){
di=i,dj=j;
}else if(islower(str[j])){
++key[str[j]-'a'];
}
}
}
dfs1(si,sj);
if(flag){
puts("YES");
}else{
puts("NO");
}
}
return 0;
}