今天的主要重点是:关于STL-set的巧用
874. 模拟行走机器人
(1)题目描述
874. 模拟行走机器人https://leetcode.cn/problems/walking-robot-simulation/description/
机器人在一个无限大小的 XY 网格平面上行走,从点 (0, 0)
处开始出发,面向北方。该机器人可以接收以下三种类型的命令 commands
:
-2
:向左转90
度-1
:向右转90
度1 <= x <= 9
:向前移动x
个单位长度
在网格上有一些格子被视为障碍物 obstacles
。第 i
个障碍物位于网格点 obstacles[i] = (xi, yi)
。
机器人无法走到障碍物上,它将会停留在障碍物的前一个网格方块上,但仍然可以继续尝试进行该路线的其余部分。
返回从原点到机器人所有经过的路径点(坐标为整数)的最大欧式距离的平方。(即,如果距离为 5
,则返回 25
)
注意:
- 北表示
+Y
方向。 - 东表示
+X
方向。 - 南表示
-Y
方向。 - 西表示
-X
方向。
示例 1:
输入:commands = [4,-1,3], obstacles = [] 输出:25 解释: 机器人开始位于 (0, 0): 1. 向北移动 4 个单位,到达 (0, 4) 2. 右转 3. 向东移动 3 个单位,到达 (3, 4) 距离原点最远的是 (3, 4) ,距离为 32 + 42 = 25
示例 2:
输入:commands = [4,-1,4,-2,4], obstacles = [[2,4]] 输出:65 解释:机器人开始位于 (0, 0): 1. 向北移动 4 个单位,到达 (0, 4) 2. 右转 3. 向东移动 1 个单位,然后被位于 (2, 4) 的障碍物阻挡,机器人停在 (1, 4) 4. 左转 5. 向北走 4 个单位,到达 (1, 8) 距离原点最远的是 (1, 8) ,距离为 12 + 82 = 65
提示:
1 <= commands.length <= 104
commands[i]
is one of the values in the list[-2,-1,1,2,3,4,5,6,7,8,9]
.0 <= obstacles.length <= 104
-3 * 104 <= xi, yi <= 3 * 104
- 答案保证小于
231
做题分析:
用自己的话解释题意:
在一个二维坐标系中,一机器人按照我们给的命令行走,遇到障碍停止,求在行走的过程中的最大距离平方。
开始思考解决方法:
题意还是很好理解的
然后也没有什么好办法
数据范围也不大
我们直接模拟大法
如何模拟?
因为我们求解是一个过程里的距离最大值
那我们就一定需要一边模拟,一边计算当时的最大值情况。
所以我们需要及时的更新我们的坐标,距离答案
转向问题:
我们可以规定一个变量,0,1,2,3分别代表四个不同的方向
四个不同的方向的前进一格的方法是:
grad_x[4]={0,1,0,-1},grad_y[4]={1,0,-1,0};
now_x+=grad_x[grad];
now_y+=grad_y[grad];
调整方向:
当读取到调整方向的指令时,如
"-1":“向右转90度”,只要当前方向grad+1就可以得到右转方向(记得%4)
"-2":“向左转90度”,只要当前方向grad+3就可以得到左转方向(记得%4)
那么今天较为重要的就是:
我们如何快速判断该点是否为障碍点?
因为数据范围摆在那里,如果每一次我们判断都循环,耗时会很多
那接下来我的想法是:
用一个bool二维数组,
想法很好
但是这个平面内还有别的象限,即有负数,数组下标不可能为负数。
接下来就引入今天的重点:
STL-set:
使用二维set作为对障碍物使用的数据结构,以便我们可以有效地检查下一步是否受阻。且int类型可以出现负数。
代码如下:
class Solution {
public:
int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
int n=commands.size(),m=obstacles.size();
int grad=0,now_x=0,now_y=0,max_ans=0,now_ans;
int grad_x[4]={0,1,0,-1},grad_y[4]={1,0,-1,0};
set<pair<int,int>> b;
for(int i=0;i<m;i++)
b.insert(make_pair(obstacles[i][0],obstacles[i][1]));
for(int i=0;i<n;i++)
{
if(commands[i]==-2)
grad+=3;//向左转90度,即向右转270度,加3。
else if(commands[i]==-1)
grad+=1;//向右转90度,加1
else //否则,就是正常移动
{
grad=grad%4;
for(int j=0;j<commands[i];j++)
{
now_x+=grad_x[grad];
now_y+=grad_y[grad];
if(b.find(make_pair(now_x, now_y))!=b.end())//到达的该点为障碍,退回上一步,并且退出循环
{
now_x-=grad_x[grad];
now_y-=grad_y[grad];
break;
}
}
now_ans=pow(now_x,2)+pow(now_y,2);
max_ans=max(max_ans,now_ans);
}
}
return max_ans;
}
};
二、总结及计划
STL!!!