题意:一个人从迷宫中,每次遇到岔路口一定转弯,除非路径唯一,不能走回头路,问最少花多少步逃出。
分析:对于每一个点来说都考虑四种方向状态记录到达该点时的方向和状态,以此为基础进行bfs
代码有些挫,有多余部分,未修改
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstdlib>
#include<cmath>
#include<vector>
//#pragma comment(linker, "/STACK:1024000000,1024000000");
using namespace std;
#define INF 0x3f3f3f3f
char g[100][100];
int G[100][100];
int n,m;
int x,y;
struct node
{
int lx,ly;
int x,y;
int step;
int d;
friend bool operator < (node A,node B)
{
return A.step>B.step;
}
};
int vis[100][100][4],dir[][5]= {{-1,0},{0,1},{0,-1},{1,0}};
bool judge(node k)
{
if(k.x==0||k.x==n-1||k.y==0||k.y==m-1) return true;
return false;
}
bool inbound(int x,int y)
{
return x>=0&&x<n&&y>=0&&y<m;
}
bool isG(int x,int y)
{
int d[5];
int num=0;
for(int i=0;i<4;i++)
{
int _x=x+dir[i][0];
int _y=y+dir[i][1];
if(inbound(_x,_y))
{
if(g[_x][_y]=='.') d[num++]=i;
}
}
if(num>=3) return true;
if(num==2)
{
if(d[0]+d[1]==3) return false;
return true;
}
return false;
}
void init()
{
memset(G,0,sizeof G);
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(g[i][j]=='@')
{
x=i;
y=j;
}
if(g[i][j]=='.')
{
if(isG(i,j))
{
G[i][j]=1;
}
}
}
}
}
int bfs()
{
memset(vis,0,sizeof vis);
priority_queue<node>que;
node k;
k.x=x;
k.y=y;
k.d=-1;
k.step=0;
k.lx=k.ly=-1;
que.push(k);
while(!que.empty())
{
k=que.top();
que.pop();
//cout<<k.x<<' '<<k.y<<endl;
if(judge(k)) return k.step;
for(int i=0; i<4; i++)
{
node temp=k;
temp.x+=dir[i][0];
temp.y+=dir[i][1];
temp.step++;
temp.d=i;
temp.lx=k.x,temp.ly=k.y;
if(inbound(temp.x,temp.y))
{
if(!vis[temp.x][temp.y][i]&&g[temp.x][temp.y]!='#')
{
if(temp.x==k.lx&&temp.y==k.ly) continue;
if(G[k.x][k.y]==0) vis[temp.x][temp.y][i]=1,que.push(temp);
else
{
if(i!=k.d) vis[temp.x][temp.y][i]=1,que.push(temp);
}
}
}
}
}
return -1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
{
scanf("%s",g[i]);
}
init();
int ans=bfs();
printf("%d\n",ans);
}
return 0;
}