BFS水题,只有遇到砖块才开炮,只需要开vis[305][305][5]来记录状态即可。注意清空队列即输出-1的情况就行。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=305;
int gx[4]={-1,1,0,0};
int gy[4]={0,0,-1,1};
int vis[maxn][maxn][5],N,M,Sx,Sy;
char mat[maxn][maxn];
struct Node
{
int x,y,f,dep;
};
int ok(int x,int y)
{
return (x>=0&&x<N&&y>=0&&y<M);
}
int ok1(int x,int y,int f,int i)
{
if(mat[x][y]=='B'&&f==i) return 1;
if(mat[x][y]=='E'||mat[x][y]=='T') return 1;
return 0;
}
queue<Node> Q;
int bfs(int sx,int sy)
{
Node nt,nt1;
nt.x=sx;nt.y=sy;nt.f=-1;nt.dep=0;
Q.push(nt); vis[sx][sy][4]=1;
while(!Q.empty())
{
nt=Q.front(); Q.pop();
if(mat[nt.x][nt.y]=='T') return nt.dep;
for(int i=0;i<4;i++)
{
int x=nt.x+gx[i],y=nt.y+gy[i];
if(!ok(x,y)) continue;
int &v1=vis[nt.x][nt.y][i];
if(mat[x][y]=='B' && !v1)
{
nt1=nt;nt1.dep+=1;nt1.f=i;
Q.push(nt1); v1=1;
}
if(mat[x][y]=='S' || mat[x][y]=='R') continue;
int &v2=vis[x][y][4];
if(ok1(x,y,nt.f,i) && !v2)
{
nt1.x=x;nt1.y=y;nt1.dep=nt.dep+1;
nt1.f=-1;
v2=1; Q.push(nt1);
}
}
}
return -1;
}
int main()
{
// freopen("test.txt","r",stdin);
while(scanf("%d%d",&N,&M) &&N && M)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<N;i++)
{
getchar();
for(int j=0;j<M;j++)
{
scanf("%c",&mat[i][j]);
if(mat[i][j]=='Y')
{
Sx=i;Sy=j;
}
}
}
printf("%d\n",bfs(Sx,Sy));
while(!Q.empty()) Q.pop();
}
return 0;
}