題意:
給出起點和終點,問分別靠着牆往左走,往右走,直接最短路分別是多少? #代表不能走,‘.’代表能走,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;
}
}