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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。