Day16-leetcode874

今天的主要重点是:关于STL-set的巧用

874. 模拟行走机器人

(1)题目描述

874. 模拟行走机器人icon-default.png?t=M85Bhttps://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!!!

接下来会更努力。

好,完美结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值