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代表无障碍物机器人可以前往 地图中相邻的每两个点之间的距离为1m。 0 <= 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; } } }
文章来源: 2018阿里笔试机器人寻路问题