874 模拟行走机器人

依题意,显然应该一步步模拟之
其中难解决的两个问题:

  1. 如何判断面对的是障碍点?
    当然可以定义一个很大的二维数组,然后将障碍点记为1,但那样极其浪费内存
    我们可以定义一个类型为pair的set,一开始将障碍点的坐标insert进set中,每走一步,判断面对的点是不是障碍点,若不是障碍点,则继续往前走,若是障碍点,则停下,等待转弯
    我这里选择了unordered_set,需要注意自己重写一个哈希类

可以参考 https://blog.csdn.net/include_not_found_/article/details/104881974

  1. 如何实现左转右转?
    可以用两个整数dx,dy来表示现在面对的方向。
    在这里插入图片描述
    可以观察出以下规律:
    右转90度时,dx = old_dy, dy = -old_dx
    左转90度是右转90度的逆过程,dx = -old_dy, dy = old_dx
    问题就很容易解决了

代码:

class s_hash
{
    public:
        inline size_t operator()(const pair<int, int> &p)const 
        {
            return (p.first + p.second) % 9209; 
            // 想不到什么好的哈希函数=。=
            // 所以简单粗暴地相加,数据在-30000到30000之间,模一个素数
        }   
};

class Solution {
public:
    int robotSim(vector<int>& commands, vector<vector<int>>& obstacles) {
        int dx = 0, dy = 1, temp; // 一开始向北
        int cur_x = 0, cur_y = 0, ans = 0;
        unordered_set<pair<int, int>, s_hash> s; // 不用自动排序加快速度
        for(auto o : obstacles) s.insert(make_pair(o[0], o[1]));
        for(auto c : commands)
        {
            if(c == -1) {temp = dx; dx = dy;  dy = -temp;}
            if(c == -2) {temp = dx; dx = -dy;  dy = temp;}
            for(int i = 0; i < c; i++) // 一步步模拟
            {
                // 无障碍,则更新,前方有障碍则等待转弯
                if(s.find(make_pair(cur_x + dx, cur_y + dy)) == s.end())
                {
                    cur_x += dx;
                    cur_y += dy;
                    ans = max(ans, cur_x * cur_x + cur_y * cur_y);
                }
            }
        }
        return ans;
    }
};
发布了21 篇原创文章 · 获赞 32 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/include_not_found_/article/details/104880541
874