链接:http://poj.org/problem?id=3083
求沿左墙走到目标点的距离,和沿右墙走到目标点的距离,以及到目标点的最短距离;
求两个沿边走的路径DFS,按照上一个点的位置分别顺时针和逆时针优先遍历就好了。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <string>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 309
#define MAXM 50007
char st[53][53];
int vis[53][53];
int dis[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int n,m;
int Ans;
struct node
{
int x,y,top,anw;
};
void DFS(int x, int y, int from, int flag)
{
int poi=(from+flag+4)%4;
for(int i=0; i<4; ++i)
{
int xx=x+dis[poi][0];
int yy=y+dis[poi][1];
if(xx<0||yy<0||xx>=n||yy>=m)
{poi=(poi+flag+4)%4;continue;}
if(st[xx][yy]!='#')
{
Ans++;
if(st[xx][yy]=='E')break;
DFS(xx,yy,(poi+2)%4,flag);
break;
}
poi=(poi+flag+4)%4;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
node S,T;
memset(vis,0,sizeof(vis));
scanf("%d%d",&m,&n);
for(int i=0; i<n; ++i)
{
getchar();
for(int j=0; j<m; ++j)
{
scanf("%c",&st[i][j]);
if(st[i][j]=='S')
{
S.x=i;S.y=j;S.top=0;
}
}
}
Ans=0;
DFS(S.x,S.y,0,1);
cout<<Ans+1<<" ";
Ans=0;
DFS(S.x,S.y,0,-1);
cout<<Ans+1<<" ";
queue<node>q;
S.anw=1;
q.push(S);
vis[S.x][S.y]=1;
bool finf=false;
while(!q.empty())
{
node ip=q.front();
q.pop();
for(int i=0; i<4; ++i)
{
int xx=ip.x+dis[i][0];
int yy=ip.y+dis[i][1];
if(xx<0||yy<0||xx>=n||yy>=m)continue;
if(vis[xx][yy])continue;
if(st[xx][yy]!='#')
{
node ne;
ne.x=xx;
ne.y=yy;
ne.anw=ip.anw+1;
if(st[xx][yy]=='E')
{
finf=true;
Ans=ne.anw;
break;
}
q.push(ne);
vis[xx][yy]=1;
}
}
if(finf)break;
}
cout<<Ans<<endl;
}
return 0;
}
/*
2
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
########
*/