入门力扣自学笔记276 C++ (题目编号:874)

874. 模拟行走机器人

题目:

机器人在一个无限大小的 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) ,距离为 3^{2} + 4^{2} = 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) ,距离为 1^{2} + 8^{2} = 65


提示:

1 <= commands.length <= 10^{4}
commands[i] is one of the values in the list [-2,-1,1,2,3,4,5,6,7,8,9].
0 <= obstacles.length <= 10^{4}
-3 * 10^{4} <= xi, yi <= 3 * 10^{4}
答案保证小于 2^{31}


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/walking-robot-simulation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路:

首先,使用两个map,x_map: key为障碍物x坐标,val为障碍物y坐标;y_map: key为障碍物y坐标,val为障碍物x坐标;这样做的目的是,由于每次行走都是沿着x或y轴方向,不存在走斜线,因此两个map帮助寻找只沿着x轴或者y轴方向某根直线的障碍物,提高效率。

其次,每一步走的时候,进行障碍物检测。注意需要分清沿着正方向还是负方向走。

最后,得到最后走的距离的最大值返回即可。


代码:

class Solution {
public:

    enum Direction
    {
        up = 1,
        down = 2,
        left = 3,
        right = 4
    };

    void turnRight(Direction& direction) 
    {
        if(direction == Direction::up)
            direction = Direction::right;
        else if(direction == Direction::down)
            direction = Direction::left;
        else if(direction == Direction::left)
            direction = Direction::up;
        else if(direction == Direction::right)
            direction = Direction::down;
    }

    void turnLeft(Direction& direction) 
    {
        if(direction == Direction::up)
            direction = Direction::left;
        else if(direction == Direction::down)
            direction = Direction::right;
        else if(direction == Direction::left)
            direction = Direction::down;
        else if(direction == Direction::right)
            direction = Direction::up;
    } 

    int collisionDetectionAndMove(int start,int end,set& obs)
    {
        bool collision = false;
        int dist = INT_MAX,after_move;
        for(const auto& o : obs)
        {
            if(o == start)
                continue;
            if((o - start) * (o - end) <= 0)
            {
                collision = true;
                int cur_after_move = start < o ? o - 1 : o + 1;
                if(abs(o - start) < dist)
                {
                    dist = abs(o - start);
                    after_move = cur_after_move;
                }
            }
        }
        if(!collision)
            return end;
        else
            return after_move;
    }   

    void proceed(Direction& direction,pair& current,int command,unordered_map>& x_map,unordered_map>& y_map,int& max_dist_square)
    {
        if(direction == Direction::up)
            current.second = collisionDetectionAndMove(current.second,current.second + command,x_map[current.first]);
        else if(direction == Direction::down)
            current.second = collisionDetectionAndMove(current.second,current.second - command,x_map[current.first]);
        else if(direction == Direction::left)
            current.first = collisionDetectionAndMove(current.first,current.first - command,y_map[current.second]);
        else if(direction == Direction::right)
            current.first = collisionDetectionAndMove(current.first,current.first + command,y_map[current.second]);
        int current_dist_square = pow(current.first,2) + pow(current.second,2);
        if(current_dist_square > max_dist_square)
            max_dist_square = current_dist_square;
    }

    int robotSim(vector& commands, vector>& obstacles) {
        unordered_map> x_map,y_map;
        Direction direction = Direction::up;
        pair current = {0,0};
        int max_dist_square = 0;
        for(const auto& vec : obstacles)
        {
            x_map[vec[0]].insert(vec[1]);
            y_map[vec[1]].insert(vec[0]);
        }
        for(const auto& command : commands)
        {
            if(command == -2)
                turnLeft(direction);
            else if(command == -1)
                turnRight(direction);
            else
                proceed(direction,current,command,x_map,y_map,max_dist_square);
        }
        return max_dist_square;
    }
};

你可能感兴趣的:(力扣算法学习,leetcode,c++,算法)