- bfs 的时候标记数组多开一维度表示是否已经取得了钥匙的状态。如果到达终点并且取得钥匙的状态被标记,bfs 结束。
- 所以我们需要把vis数组开成三维,第三个维度来标记是否拿到钥匙,也就是同一个点其实可以走两次,第一次是没拿到钥匙的时候,第二次是拿到钥匙的时候
#include<bits/stdc++.h>
using namespace std;
int n,m;
const int maxn=2011;
char mat[maxn][maxn];
bool vis[maxn][maxn][2];
int dir[4][2]= {1,0,-1,0,0,-1,0,1};
struct node
{
int x,y,step,op;
node() {}
node(int _x,int _y,int _step,int _op):x(_x),y(_y),step(_step),op(_op) {}
} st,key;
void bfs(node u)
{
queue<node>q;
q.push(u);
vis[u.x][u.y][0]=1;
while(!q.empty())
{
node f=q.front();
q.pop();
//printf("x=%d y=%d step=%d op=%d\n",f.x,f.y,f.step,f.op);
if(mat[f.x][f.y]=='T'&&f.op)
{
printf("%d\n",f.step);
return;
}
for(int i=0; i<4; i++)
{
int nx=f.x+dir[i][0];
int ny=f.y+dir[i][1];
if(vis[nx][ny][f.op]||nx<0||nx>=n||ny>=m||ny<0||mat[nx][ny]=='#')continue;
if(mat[nx][ny]=='P')
{
q.push(node(nx,ny,f.step+1,1));
vis[nx][ny][1]=1;
}
else
{
q.push(node(nx,ny,f.step+1,f.op));
vis[nx][ny][f.op]=1;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
{
scanf("%s",mat[i]);
for(int j=0; j<m; j++)
{
if(mat[i][j]=='S')
{
st.x=i;
st.y=j;
st.step=0;
st.op=0;
}
}
}
bfs(st);
return 0;
}