题意:
给出起点和终点,问分别靠着墙往左走,往右走,直接最短路分别是多少? #代表不能走,‘.’代表能走,S是起点,E是终点。
Sample Input
2
8 8
#
……
.####.
.####.
.####.
.####.
…#..
S#E
9 5
#
.#.#.#.
S…….E
.#.#.#.
#
Sample Output
37 5 5
17 17 9
分析:
这道题的主要难点就是如何选择靠右走与靠左走。在格子里如何辨别方向呢?
那这就需要人为的规定方向了。
0
1 current 3
2
比如现在,current代表现在的位置,上、左、下、右 分别用0,1,2,3表示。
那么如果是靠右走,加入自己刚从3的方向走过来,那此时自己是面朝3的,那么这个时候的右边是2,那么优先2走,如果走不通就一次向左转,所以3的方向顺序就是2301 ,同理0的方向顺序就是3012 。。。
找到这个规律就好了。向左也是一样的道理。另外审题要发现靠左右走的时候可以走重复的地方。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL long long
#define maxn 100
using namespace std;
string mp[maxn];
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};
int vis[maxn][maxn];
int n,m;
int si,sj,ei,ej;
int l,r,res,flag;
struct Node
{
int x,y,d;
}node[maxn];
void rdfs(int x,int y,int d,int dis)
{
// cout<<x<<" "<<y<<" "<<d<<endl;
if(mp[x][y]=='E')
{
r=dis;
flag=1;
return ;
}
int i,j;
d=(d+3)%4;
for(i=0;i<4;i++)
{
int t=(d+i)%4;
// cout<<t<<" ";
int tx=x+dx[t];
int ty=y+dy[t];
if(tx>=0 && tx<n && ty>=0 && ty<m && mp[tx][ty]!='#')
{
rdfs(tx,ty,t,dis+1);
if(flag)return ;
}
}
// cout<<endl;
}
void ldfs(int x,int y,int d,int dis)
{
// cout<<x<<" "<<y<<" "<<d<<endl;
if(mp[x][y]=='E')
{
l=dis;
flag=1;
return ;
}
int i,j;
d=(d+1)%4;
for(i=0;i<4;i++)
{
int t=(d-i+4)%4;
// cout<<t<<" ";
int tx=x+dx[t];
int ty=y+dy[t];
if(tx>=0 && tx<n && ty>=0 && ty<m && mp[tx][ty]!='#')
{
ldfs(tx,ty,t,dis+1);
if(flag)return ;
}
}
// cout<<endl;
}
void bfs()
{
int i,j;
Node a;
a.x=si;a.y=sj;a.d=1;
queue<Node> q;
q.push(a);
while(!q.empty())
{
Node b=q.front();
q.pop();
for(i=0;i<4;i++)
{
int tx=b.x+dx[i];
int ty=b.y+dy[i];
if(tx>=0 && tx<n && ty>=0 && ty<m && mp[tx][ty]!='#')
{
if(mp[tx][ty]=='E')
{
res=b.d+1;
return ;
}
mp[tx][ty]='#';
Node c;
c.x=tx;
c.y=ty;
c.d=b.d+1;
q.push(c);
}
}
}
}
int main()
{
// read;
int t;
scanf("%d",&t);
while(t--)
{
int i,j,d;
scanf("%d%d",&m,&n);
for(i=0;i<n;i++)
{
cin>>mp[i];
for(j=0;j<m;j++)
{
if(mp[i][j]=='S')
{
si=i;sj=j;
if(i==0)d=2;
else if(j==0)d=3;
else if(i==m)d=0;
else if(j==m)d=1;
}
}
}
l=r=0;
res=maxn*maxn;
flag=0;
rdfs(si,sj,d,1);
flag=0;
ldfs(si,sj,d,1);
bfs();
cout<<l<<" "<<r<<" "<<res<<endl;
}
}