POJ 1376-Robot(bfs广度优先搜索)

Robot
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 8497 Accepted: 2856

Description

The Robot Moving Institute is using a robot in their local store to transport different items. Of course the robot should spend only the minimum time necessary when travelling from one place in the store to another. The robot can move only along a straight line (track). All tracks form a rectangular grid. Neighbouring tracks are one meter apart. The store is a rectangle N x M meters and it is entirely covered by this grid. The distance of the track closest to the side of the store is exactly one meter. The robot has a circular shape with diameter equal to 1.6 meter. The track goes through the center of the robot. The robot always faces north, south, west or east. The tracks are in the south-north and in the west-east directions. The robot can move only in the direction it faces. The direction in which it faces can be changed at each track crossing. Initially the robot stands at a track crossing. The obstacles in the store are formed from pieces occupying 1m x 1m on the ground. Each obstacle is within a 1 x 1 square formed by the tracks. The movement of the robot is controlled by two commands. These commands are GO and TURN.
The GO command has one integer parameter n in {1,2,3}. After receiving this command the robot moves n meters in the direction it faces.

The TURN command has one parameter which is either left or right. After receiving this command the robot changes its orientation by 90o in the direction indicated by the parameter.

The execution of each command lasts one second.

Help researchers of RMI to write a program which will determine the minimal time in which the robot can move from a given starting point to a given destination.

Input

The input consists of blocks of lines. The first line of each block contains two integers M <= 50 and N <= 50 separated by one space. In each of the next M lines there are N numbers one or zero separated by one space. One represents obstacles and zero represents empty squares. (The tracks are between the squares.) The block is terminated by a line containing four positive integers B1 B2 E1 E2 each followed by one space and the word indicating the orientation of the robot at the starting point. B1, B2 are the coordinates of the square in the north-west corner of which the robot is placed (starting point). E1, E2 are the coordinates of square to the north-west corner of which the robot should move (destination point). The orientation of the robot when it has reached the destination point is not prescribed. We use (row, column)-type coordinates, i.e. the coordinates of the upper left (the most north-west) square in the store are 0,0 and the lower right (the most south-east) square are M - 1, N - 1. The orientation is given by the words north or west or south or east. The last block contains only one line with N = 0 and M = 0.

Output

The output contains one line for each block except the last block in the input. The lines are in the order corresponding to the blocks in the input. The line contains minimal number of seconds in which the robot can reach the destination point from the starting point. If there does not exist any path from the starting point to the destination point the line will contain -1.

Sample Input

9 10
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0
7 2 2 7 south
0 0

Sample Output

12

Source

题目大意:一个机器人在网格构成的轨道上(线,不是格子)运动,它的半径为1.6m,网格的规格是1m*1m,机器人每次能朝着它前进的方向运动1-3m,或者向左向右转,这些运动都花费一个单位的时间,机器人的身体不能碰着障碍物(黑色的格子)和墙壁,求机器人从起点到终点的最短时间。(机器人的坐标为左上角的格子)


解题思路:显然,这是一道bfs的题,我们把一个位置运动的5种运动方式都放入队列种,在对那5种状态继续此类操作,直到发现终点,输出时间即可。

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<time.h>
#include<map>
#include<string>
#include<algorithm>
#include<set>
#include<queue>
#define N 50000

using namespace std;

int _map[55][55];
int vis[55][55][4]; //记录是否已经看过
int dirx[4] = {0,-1,0,1}; //运动方向
int diry[4] = {1,0,-1,0};
int m, n, b1, b2, e1, e2;
char normal_dir[6]; //初始方向

struct node
{
    int x; //运动到的位置
    int y;
    int dir; //运动方向
    int time; //运动到此位置时间
};

bool can_go(int x, int y) //能否运动到此位置
{
    if(x<1 || y<1 || x>m-1 || y>n-1) //撞墙
        return false;
    if(_map[x][y] || _map[x+1][y] || _map[x][y+1] || _map[x+1][y+1]) //周围有障碍物
        return false;
    return true;
}

int normaldir(char ch) //出发时的方向
{
    if(ch == 'e') return 0;
    if(ch == 'n') return 1;
    if(ch == 'w') return 2;
    if(ch == 's') return 3;
}

int bfs()
{
    queue<node> q; //定义一个队列(队列不懂的去看看相关知识)
    node start;
    start.x = b1, start.y = b2, start.dir = normaldir(normal_dir[0]), start.time = 0;
    q.push(start); //进队列
    vis[start.x][start.y][start.dir] = 1;
    while(!q.empty()) //队列不为空
    {
        node cur;
        cur = q.front(); //取出队列首元素(第一个进队列的元素)
        if(cur.x == e1 && cur.y == e2) return cur.time; //找到终点,直接返回时间(bfs肯定最短的)
        q.pop(); //已经取出,出队
        int x = cur.x, y = cur.y;
        for(int i = 1; i <= 3; i ++){ //朝目前方向走1-3步
            x += dirx[cur.dir];
            y += diry[cur.dir];
            if(!can_go(x, y)) break; //如果前面不能走了,后面肯定也走不了
            if(!vis[x][y][cur.dir]){
                node next;
                next.x = x;
                next.y = y;
                next.dir = cur.dir;
                next.time = cur.time + 1;
                vis[next.x][next.y][next.dir] = 1;
                q.push(next); //入队一种方式
            }
        }
        for(int i = 0; i < 4; i ++){ //两个转向
            if(max(cur.dir, i) - min(cur.dir, i) == 2) //不能反向
                continue;
            if(vis[cur.x][cur.y][i])
                continue;
            node next;
            next.x = cur.x;
            next.y = cur.y;
            next.dir = i;
            next.time = cur.time + 1;
            vis[next.x][next.y][next.dir] = 1;
            q.push(next); //入队一种方式
        }
    }
    return -1; //不能到达,输出-1
}

int main()
{
    while(scanf("%d%d", &m, &n) && m && n)
    {
        memset(_map, 0, sizeof(_map));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= m;i ++)
            for(int j = 1; j <= n; j ++)
            scanf("%d", &_map[i][j]);
        scanf("%d%d%d%d%s", &b1, &b2, &e1, &e2, normal_dir);
        printf("%d\n",bfs());
    }
    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值