题目:http://poj.org/problem?id=3083
题目的大意就是:输入一个类似迷宫的东西,其中S表示起点,E表示终点,#表示墙壁,,表示空地。其中S,E一定在边缘,并且S一定能到达E
例如:
######## #......# #.####.# #.####.# #.####.# #.####.# #...#..# #S#E####
求人从S出发,到达E的过程需要走几步?走的方式有三种,靠左走,靠右走,以及最短路径的走法,分别输出步数
以上面的输入为例,靠左走:37步; 靠右走:5步; 最短:5步
最短路径的肯定采用bfs;
重点理解是靠左走,靠右走;
假设我们 下 ,左 ,上 ,右 四个方向编号为 0,1 , 2,3
靠左走分四种情况:
(1)目前的行走朝向是 上 ,则考虑的朝向的优先级(由高到低),左,上,右,下 ; 对应编号: 2 , 1 2 3 0
(2)目前的行走朝向是 下 ,则考虑的朝向的优先级(由高到低),右,下,左,上 ;对应编号: 0 , 3 0 1 2
(3)目前的行走朝向是 右 ,则考虑的朝向的优先级(由高到低),上,右,下,左 ;对应编号: 3 , 2 3 0 1
(4)目前的行走朝向是 左 ,则考虑的朝向的优先级(由高到低),下,左,上,右 ; 对应编号: 1 , 0 1 2 3
靠右走分四种情况:
(1)目前的行走朝向是 上 ,则考虑的朝向的优先级(由高到低),右,上,左,下 ;对应编号: 2 , 3 2 1 0
(2)目前的行走朝向是 下 ,则考虑的朝向的优先级(由高到低),左,下,右,上 ;对应编号: 0 , 1 0 3 2
(3)目前的行走朝向是 右 ,则考虑的朝向的优先级(由高到低),下,右,上,左 ;对应编号: 3 , 0 3 2 1
(4)目前的行走朝向是 左 ,则考虑的朝向的优先级(由高到低),上,左,下,右 ;对应编号: 1 , 2 1 0 3
假设当前的朝向编号为m,朝向的编号最高优先级为n;
则:
靠左走:n=(m+3)%4; n=(n+1)%4;
靠右走:n=(m+1)%4; n=(n+3)%4;
源码实现如下:
//3083
#include<iostream>
#include <cstring>
using namespace std;
const int N=45;
typedef struct _node
{
int x;
int y;
}Node;
char maze[N][N];
int visited[N][N];
int dir[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
int w,h;
Node Q[N*N];
int Pre[N][N][2];
int direct;
bool ldfs(int x, int y, int step)
{
if (maze[x][y] == 'E')
{
cout<<step<<" ";
return true;
}
direct = (direct + 3) % 4; //靠左手边走
while(1)
{
int tmpx=x + dir[direct][0];
int tmpy=y + dir[direct][1];
if (tmpx<h&&tmpx>=0&&tmpy<w&&tmpy>=0)
{
if (maze[tmpx][tmpy]=='.'||maze[tmpx][tmpy]=='E')
{
if(ldfs(tmpx, tmpy, step + 1)) return true;
}
}
direct = (direct + 1) % 4; //顺时针
}
}
bool rdfs(int x, int y, int step)
{
if (maze[x][y] == 'E')
{
cout<<step<<" ";
return true;
}
direct = (direct + 1) % 4; //靠右手边走
while(1)
{
int tmpx=x + dir[direct][0];
int tmpy=y + dir[direct][1];
if (tmpx<h&&tmpx>=0&&tmpy<w&&tmpy>=0)
{
if (maze[tmpx][tmpy]=='.'||maze[tmpx][tmpy]=='E')
{
if(rdfs(tmpx, tmpy, step + 1)) return true;
}
}
direct = (direct + 3) % 4; //逆时针
}
}
int BFS(int r,int c)
{
visited[r][c] = 1;
Node node; node.x=r; node.y=c;
Q[0]=node;
int first=-1,last=0;
int cnt=0;
while(first!=last)
{
Node v=Q[++first];
for (int i=0;i<4;i++)
{
int x=v.x+dir[i][0];
int y=v.y+dir[i][1];
if (x<h&&x>=0&&y<w&&y>=0)
{
if ((maze[x][y]=='.'||maze[x][y]=='E')&&(visited[x][y]==0))
{
node.x=x;node.y=y;
Pre[x][y][0]=v.x;
Pre[x][y][1]=v.y;
Q[++last]=node;
visited[x][y] = 1;
}
if (maze[x][y]=='E')
{
int x0,y0;
x0=Q[last].x;
y0=Q[last].y;
while (x0!=-1)
{
cnt++;
int tmp=x0;
x0=Pre[x0][y0][0];
y0=Pre[tmp][y0][1];
}
return cnt;
}
}
}
}
}
int main()
{
int n,i,j;
cin>>n;
while (n--)
{
cin>>w>>h;
memset(visited,0,sizeof(visited));
int r,c;
for (i=0;i<h;i++)
{
for (j=0;j<w;j++)
{
cin>>maze[i][j];
if (maze[i][j]=='S')
{
r=i;c=j;
}
}
}
direct = 0; ldfs(r, c, 1);
direct = 0; rdfs(r, c, 1);
Pre[r][c][0]=-1;
Pre[r][c][1]=-1;
cout<<BFS(r,c)<<endl;
}
return 0;
}