这个题虽说是一个简单的BFS问题,但是耗费了我好长时间,而且AC的是相当蛋疼。关键注意几下几点:
1:血的教训:可能初始位置即为出口位置(即初始就在房间的边缘),此时所用时间为0.
2:每一个格子要保存是从哪个方向到达的。也就是曾经有哪一个方向到达了它,只有曾经在某个方向从没到达过它,这时才入栈...
3:再就是不能回头。
AC代码:
#include<iostream>
#include<queue>
using namespace std;
char map[85][85];
int data[85][85][4];
int directx[4]={1,0,-1,0};
int directy[4]={0,1,0,-1};
typedef struct{
int x,y,direction,time;
}Node;
int BFS(int h,int w,int ex,int ey)
{
if((ex==0) || (ex==h-1) || (ey==0) || (ey==w-1))
return 0;
queue<Node> Q;
Node node,node1;
int dx,dy,dtime,ddrection;
node.x=ex;
node.y=ey;
node.time=0;
node.direction=-1;
Q.push(node);
while(!Q.empty())
{
node=Q.front();
Q.pop();
for(int i=0;i<4;++i)
{
if(i%2==0 && (node.direction)%2==0)
{
if((map[node.x+directx[1]][node.y+directy[1]]!='#') ||(map[node.x+directx[3]][node.y+directy[3]]!='#'))
continue;
}
else if(i%2==1 && (node.direction)%2==1)
{
if((map[node.x+directx[0]][node.y+directy[0]]!='#') || (map[node.x+directx[2]][node.y+directy[2]]!='#'))
continue;
}
if((node.direction%2==i%2) && (node.direction!=i))//判断不能回头
continue;
dx=node.x+directx[i];
dy=node.y+directy[i];
dtime=node.time+1;
ddrection=i;
if(dx>=0 && dx<h && dy>=0 && dy<w)
{
if((map[dx][dy]=='.') && ((dx==0) || (dx==h-1) || (dy==0) || (dy==w-1)))
return dtime;
if(map[dx][dy]=='#')
continue;
node1.x=dx;
node1.y=dy;
node1.time=dtime;
node1.direction=ddrection;
if(!data[dx][dy][ddrection])
{
data[dx][dy][ddrection]=1;
Q.push(node1);
}
}
}
}
return -1;
}
int main()
{
int t,h,w,ex,ey;
cin>>t;
while(t--)
{
memset(map,0,sizeof(map));
memset(data,0,sizeof(data));
cin>>h>>w;
for(int i=0;i<h;++i)
{
for(int j=0;j<w;++j)
{
cin>>map[i][j];
if(map[i][j]=='@')
{
ex=i;
ey=j;
}
}
}
cout<<BFS(h,w,ex,ey)<<endl;
}
return 0;
}