题目大意:
1. 迷宫,S是起点,E是终点,#是墙不可走,.可以走
2. 输出左转优先的步数
3.在输出右转优先的步数
4.在输出最短的步数
解题技巧:
♢ 关键是方向转动的表示 可以用转向公式
左转,用数学式子表达就是 d=(d+1)%4;
右转,用数学式子表达就是 d=(d+3)%4;
♢ 不论是左转优先还是右转优先,都用DFS
最短步数用BFS 求解
注意要点:
需要注意一下“Exactly one 'S' and one 'E' will be present in the maze, and they will always be located along one of the maze edges and never in a corner.”即始点‘S’和终点‘E’一定都与迷宫的边界相邻,做题很关键。
//Time:0MS
//Memor:297K
#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
#define MAX 50
using namespace std;
struct point
{
int x , y;
int step;
};
int visit[MAX][MAX]; //访问标志
char maze[MAX][MAX]; //存储迷宫
int mov_left[4][2] = {{0,-1},{1,0},{0,1},{-1,0}} ; // 靠左走
int mov_righ[4][2] = {{0,1},{1,0},{0,-1},{-1,0}} ; // 靠右走
int d1 , d2 ;
int start[2]; //起点
int finish[2]; //终点
int w , h ;
int dfs(int x,int y,int d,int move[][2])
{
int step ,temp , tx , ty ;
if(x == finish[0] && y == finish[1]) // 剪枝
return 1 ;
for(int i = 0; i < 4 ; i++)
{
temp = (d + i) % 4 ;
tx = x + move[temp][1] ; //当前 x坐标
ty = y + move[temp][0] ; //当前 y坐标
if(tx>=0 && tx<h && ty>=0 && ty<w && !visit[tx][ty])
break ;
}
step = dfs(tx,ty,(temp + 3)%4,move) + 1; //递归搜索 ,更新步数
return step;
}
int bfs() //广搜求最短步数
{
memset(visit,0,sizeof(visit));
queue<point> Q;
point p;
p.x = start[0] ;
p.y = start[1] ;
p.step = 1;
visit[p.x][p.y] = 1 ;
Q.push(p);
while(!Q.empty())
{
p = Q.front();
Q.pop();
if(p.x == finish[0] && p.y == finish[1])
return p.step ;
for(int i = 0 ; i < 4 ; i ++)
{
point temp ;
temp.x = p.x + mov_left[i][1] ;
temp.y = p.y + mov_left[i][0] ;
if(temp.x>=0 && temp.x<h && temp.y>=0 && temp.y<w && maze[temp.x][temp.y]!='#' && !visit[temp.x][temp.y])
{
visit[temp.x][temp.y] = 1;
temp.step = p.step + 1 ;
Q.push(temp) ;
}
}
}
return 0;
}
int main()
{
freopen("in.txt","r",stdin);
int n;
cin>>n;
while(n--)
{
int i , j ;
cin>>w>>h;
memset(visit,0,sizeof(visit));
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
cin>>maze[i][j];
if(maze[i][j] == '#') //障碍物不可走
{
visit[i][j] = 1;
}
if(maze[i][j] == 'S') // 起点坐标
{
start[0] = i ;
start[1] = j ;
}
if(maze[i][j] == 'E') //终点坐标
{
finish[0] = i ;
finish[1] = j ;
}
}
}
if(start[0] == 0)
{
d1 = 1 ;
d2 = 1 ;
}
else if(start[0] == h-1)
{
d1 = 3 ;
d2 = 3 ;
}
else if(start[0] == w-1)
{
d1 = 2 ;
d2 = 0 ;
}
else
{
d1 = 0 ;
d2 = 2 ;
}
cout<<dfs(start[0],start[1],d1,mov_left)<<" ";
cout<<dfs(start[0],start[1],d2,mov_righ)<<" ";
cout<<bfs()<<endl;
}
return 0;
}