2018阿里笔试机器人寻路问题

1 在自动化仓库中有若干障碍物,机器人需要从起点出发绕过这些障碍物到终点搬取货柜,现试求机器人从起点运动到终点用时最短的路径。 已知机器人只能沿着东西方向或南北方向移动,移动的速度为1m/s,机器人每转向90度需要花费1s。


 输入: 
第一行:起点位置坐标及机器人朝向,如: 
1 0 EAST
代表机器人初始坐标为x=1,y=0,机器人面朝东方 
第二行:终点位置坐标及机器人朝向,如: 
0 2 WEST
代表机器人需要移动至点x=0,y=2,且面朝西方 
接下来输入的是地图: 
首先是两个数字r,c,代表有地图数据有多少行与多少列,如:
2 3
0 1 0
0 0 0 
其中,左上角为坐标原点,从左向右为x轴增大的方向是东方,从上到下为y轴增大的方向是南方。
地图中1代表有障碍物,机器人不能前往,0代表无障碍物机器人可以前往 地图中相邻的每两个点之间的距离为1m0 <= l,w <= 128 

输出: 
机器人从起点移动到终点所需要的最短秒数,当不可达时输出65535

思路: bfs+优先队列

// author : L
// 以下代码为:bfs+前缀数组记录路径+优先队列记录当前最优。只需要更改部分即可达到题目要求。
// 如果有读者不会改的,可以在评论留言。
// bfs编写并没有考虑,走不到的情况,record记录了当前所经过的路径。
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef pair<int,int> P;
const int NORTH = 0;
const int SOUTH = 1;
const int WEST = 2;
const int EAST = 3;
struct Point
{
    int x_;
    int y_;
    int time_;        //机器人走到当前所需要的时间;
    int direction_;   //机器人当前的方向;
    friend  bool operator<(Point a, Point b)
    {
        return a.time_ > b.time_;   //定义从小到大排列;
    }
};

typedef pair<int,int> P;

int direction_[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};  // up down left right;

int change(int direction,int up) //机器人转向
{
    if( direction == NORTH)
    {
        switch(up)
        {
        case 0:
            return 0;
        case 1:
            return 2;
        case 2:
            return 1;
        case 3:
            return 1;
        default:
            return -1;
        }
    }
    else if(direction == SOUTH)
    {
        switch(up)
        {
        case 0:
            return  2;
        case 1:
            return  0;
        case 2:
            return  1;
        case 3:
            return  1;
        default:
            return -1;
        }
    }
    else if(direction == WEST)
    {
        switch(up)
        {
        case 0:
            return 1;
        case 1:
            return 1;
        case 2:
            return 0;
        case 3:
            return 2;
        default:
            return -1;
        }
    }
    else if(direction == EAST)
    {
        switch(up)
        {
        case 0:
            return 1;
        case 1:
            return 1;
        case 2:
            return 2;
        case 3:
            return 0;
        default:
            return -1;
        }
    }
}
// Point为了更加简单方便的记录;
void bfs(vector<vector<char>> &maze, vector<int>& record, vector<vector<bool>>& visited, int start_x, int start_y, int end_x, int end_y, int direction);
int main()
{
    char input[4][4]  = {{'.','X','X','.'},{'.','.','X','X'},{'.','.','.','.'},{'.','X','.','.'}};


    int n,m;

    int direction;

    int start_x, start_y;

    int end_x, end_y;

    cin>>n>>m;

    cin>>direction;

    cin>>start_x>>start_y;  // 起始点;

    cin>>end_x>>end_y;      // 结束点;

    vector<vector<char>> maze(n,vector<char>(m,0));

    vector<int> record;

    vector<vector<bool>> visited(n,vector<bool>(m,false));

    vector<P> result;

    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            maze[i][j] = input[i][j];
        }
    }

    bfs(maze,record,visited,start_x,start_y,end_x,end_y,direction);

    P p;

    for(int i=m*n-1; i>=0;)
    {
        if(record[i] == -1)
        {
            p.first = 0;
            p.second = 0;
            result.push_back(p);
            break;
        }
        else
        {
            p.first = i/m;
            p.second = i%m;
            result.push_back(p);
            i = record[i];
        }
    }
    reverse(result.begin(),result.end());
    for(int i=0; i<result.size(); i++)
    {
        cout<<"("<<result[i].first<<","<<result[i].second<<")"<<" ";
    }
    //
    return 0;
}
void bfs(vector<vector<char>> &maze, vector<int>& record, vector<vector<bool>>& visited, int start_x, int start_y, int end_x, int end_y, int direction)
{
    priority_queue<Point> que_;

    int n  = maze.size();
    int m  = maze[0].size();

    Point temp;
    temp.x_ = start_x;
    temp.y_ = start_y;
    temp.time_ = 0;
    temp.direction_ =  direction;
    record[0] = -1;
    que_.push(temp);

    while(!que_.empty())
    {
        Point p = que_.top();

        for(int i=0; i<4; i++)  //分别是上下左右;
        {

            int x = p.x_+direction_[i][0];

            int y = p.y_ + direction_[i][1];

            int time = change(p.direction_,i);  //转圈所需要的时间;

            if(x == end_x && y == end_y)
            {
                //record the route;
            }

            if( x>=0 && x<maze.size() && y>=0 && y<maze[0].size() && visited[x][y] == false && maze[x][y] != 'X')
            {
                Point t;

                visited[x][y] = true;

                t.x_ = x;

                t.y_ = y;

                t.time_ = time+1; //所需要的实际时间;

                t.direction_ = i; //新的direction;

                que_.push(t);

                record[x*m+y] = p.x_*m+p.y_; //record记录前驱信息;

                if(x == end_x && y == end_y) break;
            }

            if(i!=4) break;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值