Solution
“如果走投无路,试试打开一扇门,或许能绝处逢生”
所以思路就是当队列为空时,把所有曾经经过且找到全部对应钥匙的门加入队列(从wait数组里找),注意是所有的,而且入队后不能将其从wait数组中移出。而经过一扇门时,无论是否找到所有对应钥匙,都不入队,只将其加入wait数组。
为什么呢?因为路是可以重复走的,所以我们并不知道曾经哪扇门可以到达终点,这次从wait数组入队但未能到达终点并不意味着下次也不可以,也就是说,wait数组会越来越长。
另外有一点,如果真的“走投无路”,那么就会死循环,因为队列会一遍遍清空,而wait数组不会缩短,就只能一遍遍加入队列,永远跑不出来。
于是我机智(zei)地假设它如果不是“走投无路”的话,wait数组加入队列的次数不会超过15次。如果超过,就判断为无法到达
至于15是怎么来的,嗯猜的,也许数据水吧
Code
// by spli
#include<cstring>
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int n,m;
char s[25][25];
int num[10];
struct node{
int x,y;
};
queue<node>q;//队列
int wx[100],wy[100];//wait数组
int head;
int tim;//加入次数
bool vis[25][25];//记录是否入队
bool can[25][25];//记录是否加入wait数组
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,1,0,-1};
int ax,ay;
void bfs(){
node f;
int x,y,kx,ky;
while(!q.empty()){
f=q.front();
q.pop();
x=f.x;y=f.y;
for(int i=1;i<=4;++i){
kx=x+dx[i];
ky=y+dy[i];
if(s[kx][ky]>='A'&&s[kx][ky]<='E'){
if(can[kx][ky]) continue;
can[kx][ky]=1;
wx[head]=kx;
wy[head++]=ky;
}
else if(kx>=1&&kx<=n&&ky>=1&&ky<=m&&!vis[kx][ky]&&s[kx][ky]!='X'){
vis[kx][ky]=1;
q.push((node){kx,ky});
if(s[kx][ky]>='a'&&s[kx][ky]<='e')
num[s[kx][ky]-'a']--;
}
}
if(vis[ax][ay]) return;
if(q.empty()&&tim<15){ //骗分哈哈哈
++tim;
for(int j=0;j<head;++j){ //全部入队
x=wx[j],y=wy[j];
//if(!(x+y)) continue;
if(!num[s[x][y]-'A']) q.push((node){x,y});
//wx[j]=wy[j]=0;不能移出wait数组
}
}
}
}
int main(){
while(scanf("%d%d",&n,&m)&&n&&m){
for(int i=0;i<10;++i) num[i]=0;
tim=head=0;
while(!q.empty()) q.pop();
for(int i=1;i<=n;++i){
scanf("%s",s[i]+1);
for(int j=1;j<=m;++j){
vis[i][j]=can[i][j]=0;
if(s[i][j]=='S') q.push((node){i,j}),vis[i][j]=1;
if(s[i][j]>='a'&&s[i][j]<='e') num[s[i][j]-'a']++;
if(s[i][j]=='G') ax=i,ay=j;
}
}
bfs();
if(vis[ax][ay]) printf("YES\n");
else printf("NO\n");
}
return 0;
}
//以下是poj讨论区的几组数据
/*
7 5
S..AG
c...X
XXCXX
b....
XXXBX
a....
XXXXX
*/
/*
4 4
S.X.
a.X.
..XG
....
3 4
S.Xa
.aXB
b.AG
0 0
*/
/*
11 6
X.XXE.
X.GXX.
.D.dXS
...X..
.X.Xac
..XXaX
X..X.X
X..a.B
XA..Cc
.XX..X
...X.X
6 8
S......D
X.X.X.X.
XeX.X.Xc
bA..XeXB
XXX.XbXE
aCd.XaXG
5 7
S.....D
XX.X.Xc
bA.XeXB
XX.XbXE
aCdXaXG
11 6
X.XXE.
X.GXX.
.D.dXS
...X..
.X.Xac
..XXaX
X..X.X
X..a.B
XA..Cc
.XX..X
...X.X
12 13
S............
aXXXXXAXXXXX.
bXXXXXbXXXXX.
cXXXXXeXXXXX.
dXXXXXXXXXXX.
eXXXXXXXXXXX.
.BcXXG.Xe....
.XXXXX.XXXXX.
.XXXXX.XXXXX.
.CdDeX.....E.
.XXXXXXXXXXX.
.............
20 20
....................
.XXXXXXXXXXAXXXXXXX.
.X................X.
.X.XXXXXXXXXXXXXX.X.
.X.X............X.X.
.X.X.XXXXXXXXXX.X.X.
.X.X.XcX......X.X.X.
.X.X.X.XDXXXX.X.X.X.
.X.X.X.X.XXXX.X.X.X.
.X.X.X.X.E.GX.X.X.X.
aX.X.X.X.XXXX.C.X.X.
.X.X.X.X...eX.X.X.X.
.X.X.X.XXXXXXdX.X.X.
.X.X.X......dXX.X.X.
.X.X.XXXXX.XXXX.X.X.
.X.X............X.X.
.X.XXXXXXXBXXXXXX.X.
.X...............bX.
.XXXXXXXXXXXXXXXXXX.
.................S..
0 0
*/
/*
20 20
S..................a
aXXXXXXXXXXAXXXXXXX.
.X........bb......X.
.XbXXXXXXXXXXXXXX.X.
.X.X.....c......X.X.
aXbX.XXXXXXXXXX.X.X.
.X.X.X........X.X.X.
.X.X.X.XDXXXX.X.X.X.
.X.X.X.X..XXX.X.X.X.
.X.X.X.X.XG.X.X.X.X.
.X.XcX.X.XXEX.CeX.X.
.X.X.X.X.e..X.X.X.X.
.X.X.X.XXXXXX.X.X.X.
.X.X.X........X.X.X.
.X.X.XXXXXXXXXX.X.X.
.X.X..c.........X.X.
.X.XXXXXXXBXXXXXX.X.
.X........b.......X.
.XXXXXXXXXXXXXXXXXX.
.d..e...a........a..
*/
/*
20 20
S...................
.XXXXXXXXXXAXXXXXXX.
.X...........a....X.
.X.XXXXXXXXXXXXXX.X.
.X.X............X.X.
.X.X.XXXXXXXXXX.X.X.
.X.X.X........X.X.X.
.X.X.X.XDXXXX.X.X.X.
.X.X.X.X..XXX.X.X.X.
.X.X.X.X.XG.X.X.X.X.
.X.X.X.X.XXEX.C.X.X.
.X.X.X.X....X.X.X.X.
.X.X.X.XXXXXX.X.X.X.
.X.X.X........X.X.X.
.X.X.XXXXXXXXXX.X.X.
.X.X............X.X.
.X.XXXXXXXBXXXXXX.X.
.X................X.
.XXXXXXXXXXXXXXXXXX.
....................
*/
/*
4 5
S..AG
.XX.X
BX...
aX.Xb
0 0
*/