TOJ---2470 Robot in Maze【广度优先搜索】

There is a robot trapped in the maze. Now you have to send out some instructions, telling it how to reach its destination.

The maze is an M * N grid. Some of the cells are empty, while others are occupied by the wall. Of course the robot can't move into the wall, and the robot can't move outside the grid too. The robot can only accept three commands: TURN LEFT, TURN RIGHT and GO. The robot may face to North, South, East or West during the movement. When it receive a TURN LEFT command, it will rotate 90 degree to the left. That is, if it faces to east before the command, it will face to north after the TURN LEFT command. The TURN RIGHT command is almost the same, except that the direction is opposite. When receive the GO command, the robot will move 1 unit towards its orientation, unless there is a nonempty cell in front of it.

Please note the robot is always face to north at the beginning, i.e., face to the upper border in the maze map. (The maze map will be described below.)

You want to use minimum number of instructions, so you should write a program for help.

Input

The first line of the input is the number of test cases.

The first line of each test case contains two integers M and N, indicating the size of the maze. There are M lines followed, each line contains exactly N characters, describing an M * N maze. The '#' indicating the wall, the '.' indicating the empty cell, the 'S' and 'T' indicating the start point and the destination of the robot respectively. There are no other characters in the maze map.

The orientation of the maze map is just the same as the common sense. That is, the upper-left corner of the maze map indicating the north-west direction, and the lower-right corner indicating the south-east.

You can assume 1 ≤ M ≤ 100 and 1 ≤ N ≤ 100. There is only one 'S' and one 'T' in the maze.

Output

Output one line for each test case, indicating the minimum number of instructions needed. Or output -1 if it's impossible to reach the robot's destination.

Sample Input

2
5 5
#####
#...#
#.#.#
#S#T#
#####
4 5
#.#.#
#.#.#
#S#T#
#####

Sample Output

8

-1

SOURCE:点击打开链接

题意:

机器人在M*N的迷宫中,“#”表示墙,不能走,“.“表示通路,“S”为其实地点,“T”为终点,该机器人有三种操作,直行、左转、右转。机器人在起始位置面朝北,问机器人走出迷宫所需要的最少操作数。

解析:

很明显的广度优先搜索,难点在于只能直行、左转、右转。因此需要用一个三维数组visited[x][y][face],来记录机器人所在的位置及其状态。

代码:

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

char str[105][105];
int visited[105][105][4];
int dx[4]= {-1,0,1,0};
int dy[4]= {0,1,0,-1};
int M,N;

class node
{
public:
    int x;
    int y;
    int face;
    int step;
    node() {};
    node(const int x,const int y,const int face,const int step);
};

node::node(const int x,const int y,const int face,const int step)
{
    this->x=x;
    this->y=y;
    this->face=face;
    this->step=step;
}

int bfs(const int x,const int y);

int main(void)
{
    int T,x,y;
    cin>>T;
    while(T--)
    {
        memset(visited,0,sizeof(visited));
        cin>>M>>N;
        for(int i=0; i<M; i++)
            for(int j=0; j<N; j++)
            {
                cin>>str[i][j];
                if(str[i][j]=='S')   //记录起点位置
                {
                    x=i;
                    y=j;
                }
            }
        cout<<bfs(x,y)<<endl;
    }
    return 0;
}

int bfs(const int x,const int y)
{
    queue<node> Q;   //定义一个元素为将结构体node的队列
    int nx,ny,face,step;
    node n;
    Q.push(node(x,y,0,0));   //将起点加入队列
    visited[x][y][0]=1;
    while(Q.size())
    {
        n=Q.front();
        Q.pop();
        if(str[n.x][n.y]=='T')
            return n.step;
        nx=n.x+dx[n.face];   //向前走
        ny=n.y+dy[n.face];
        face=n.face;
        step=n.step+1;
        if(nx>=0&&nx<M&&ny>=0&&ny<N&&str[nx][ny]!='#'&&!visited[nx][ny][face])//判断是否访问过,是否越界、是否能走
        {
            Q.push(node(nx,ny,face,step));
            visited[nx][ny][face]=1;
            if(str[n.x][n.y]=='T')
                return step;
        }
        nx=n.x;   //向右转
        ny=n.y;
        face=(n.face+1)%4;
        step=n.step+1;
        if(!visited[nx][ny][face])
        {
            Q.push(node(nx,ny,face,step));
            visited[nx][ny][face]=1;
        }
        nx=n.x;   //向左转
        ny=n.y;
        face=(n.face+3)%4;
        step=n.step+1;
        if(!visited[nx][ny][face])
        {
            Q.push(node(nx,ny,face,step));
            visited[nx][ny][face]=1;
        }
    }
    return -1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值