#leetCode刷题纪实 Day17
https://leetcode-cn.com/problems/walking-robot-simulation/
机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令:
-2:向左转 90 度
-1:向右转 90 度
1 <= x <= 9:向前移动 x 个单位长度
在网格上有一些格子被视为障碍物。
第 i 个障碍物位于网格点 (obstacles[i][0], obstacles[i][1])
如果机器人试图走到障碍物上方,那么它将停留在障碍物的前一个网格方块上,但仍然可以继续该路线的其余部分。
返回从原点到机器人的最大欧式距离的平方。
示例 1:
输入: commands = [4,-1,3], obstacles = []
输出: 25
解释: 机器人将会到达 (3, 4)
示例 2:
输入: commands = [4,-1,4,-2,4], obstacles = [[2,4]]
输出: 65
解释: 机器人在左转走到 (1, 8) 之前将被困在 (1, 4) 处
提示:
0 <= commands.length <= 10000
0 <= obstacles.length <= 10000
-30000 <= obstacle[i][0] <= 30000
-30000 <= obstacle[i][1] <= 30000
答案保证小于 2 ^ 31
小菜鸡的尝试:
先以实现为目的的暴力求解,记录下此刻机器人的位置,和上一步机器人的位置,通过遍历障碍物,来判断此次行走是否会受到阻碍。(但可能是因为我菜,在写代码逻辑的时候磕磕拌拌,最后也没有通过全部样例)(如果有大佬经过,希望可以帮忙看看代码555)
1 class Solution { 2 public: 3 int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) { 4 vector<int> po {0, 0}; 5 vector<int> pre {0, 0}; 6 vector<int> statusList {0, 1, 2, 3}; 7 int status = 0; 8 for (int i = 0; i < commands.size(); i ++) { 9 cout << "执行到第" << i << "步" << endl; 10 if (commands[i] == -2) { 11 status = statusList[(status - 1 + 4) % 4]; 12 cout << "现在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 13 continue; 14 } 15 if (commands[i] == -1) { 16 status = statusList[(status + 1 + 4) % 4]; 17 cout << "现在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 18 continue; 19 } 20 if (status == 0) { // 向上走 21 pre = po; 22 po[1] = po[1] + commands[i]; 23 for (int j = 0; j < obstacles.size(); j ++) { 24 cout << "上一步的位置是 (" << pre[0] << "," << pre[1] << ")" << endl; 25 if (obstacles[j][1] <= po[1] && obstacles[j][0] == po[0] && obstacles[j][1] > pre[1] && obstacles[j][0] == pre[0]) { 26 po[1] = obstacles[j][1] - 1; 27 cout << "第" << i << "步被障碍阻塞" << endl; 28 } 29 } 30 cout << "现在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 31 } else if (status == 1) { // 向右走 32 pre = po; 33 po[0] = po[0] + commands[i]; 34 for (int j = 0; j < obstacles.size(); j ++) { 35 cout << "上一步的位置是 (" << pre[0] << "," << pre[1] << ")" << endl; 36 if (obstacles[j][0] <= po[0] && obstacles[j][1] == po[1] && obstacles[j][0] > pre[0] && obstacles[j][1] == pre[1]) { 37 po[0] = obstacles[j][0] - 1; 38 cout << "第" << i << "步被障碍阻塞" << endl; 39 } 40 } 41 cout << "现在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 42 } else if (status == 2) { // 向下走 43 pre = po; 44 po[1] = po[1] - commands[i]; 45 for (int j = 0; j < obstacles.size(); j ++) { 46 cout << "上一步的位置是 (" << pre[0] << "," << pre[1] << ")" << endl; 47 if (obstacles[j][1] >= po[1] && obstacles[j][0] == po[0] && obstacles[j][1] < pre[1] && obstacles[j][0] == pre[0]) { 48 po[1] = obstacles[j][1] + 1; 49 cout << "第" << i << "步被障碍阻塞" << endl; 50 } 51 } 52 cout << "现在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 53 } else if (status == 3) { // 向左走 54 pre = po; 55 po[0] = po[0] - commands[i]; 56 for (int j = 0; j < obstacles.size(); j ++) { 57 cout << "上一步的位置是 (" << pre[0] << "," << pre[1] << ")" << endl; 58 if (obstacles[j][0] >= po[0] && obstacles[j][1] == po[1] && obstacles[j][0] < pre[0] && obstacles[j][1] == pre[1]) { 59 po[0] = obstacles[j][0] + 1; 60 cout << "第" << i << "步被障碍阻塞" << endl; 61 } 62 } 63 cout << "现在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 64 } 65 } 66 int result = 0; 67 cout << "最后在的位置是 (" << po[0] << "," << po[1] << ")" << endl; 68 result = po[0] * po[0] + po[1] * po[1]; 69 return result; 70 } 71 };
膜拜大佬代码:
1 class Solution { 2 public: 3 int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) { 4 int dx[4] = {0,1,0,-1}; 5 int dy[4] = {1,0,-1,0}; 6 set<pair<int, int>> obs; // 用set存储障碍物 7 for(auto i:obstacles) { 8 if(i.size()>0) { 9 obs.insert(pair(i[0],i[1])); 10 } 11 } 12 int x=0,y=0; // 起点(0, 0) 13 int din = 0; // 方向 14 int res = 0; 15 for(auto com:commands) { 16 if(com>0) { // 是行进指令 17 while(com--) { 18 x+=dx[din]; 19 y+=dy[din]; 20 if (obs.find(pair(x,y))!=obs.end()) { 21 x-=dx[din]; 22 y-=dy[din]; 23 break; 24 } 25 res = max(res,x*x+y*y); 26 } 27 } else { // 是转向指令 28 din = (din+com*2+7)%4; // 魔法操作哈哈哈 29 } 30 } 31 return res; 32 } 33 };
基本思路是一样的,大佬的思路是将转向转化为横纵坐标的同时变化(如向左走就是横坐标进行-1*n操作,纵坐标进行0*n操作),刚开始我质疑过耗时,因为大佬采用了一格一格走。不过大佬在判断遇障的过程省下了时间,用Map存储障碍物(个人觉得Hashmap更快哦)节省了遍历的时间。大佬的转向操作还是挺魔法的哈哈哈
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/walking-robot-simulation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。