leetcode 874 Robot Simulation

leetcode 874 Robot Simulation

限制:32MB, 1s

描述

A robot on an infinite grid starts at point (0, 0) and faces north. The robot can receive one of three possible types of commands:

-2: turn left 90 degrees

-1: turn right 90 degrees

1 <= x <= 9: move forward x units

Some of the grid squares are obstacles.

The i-th obstacle is at grid point (obstacles[i][0], obstacles[i][1])

If the robot would try to move onto them, the robot stays on the previous grid square instead (but still continues following the rest of the route.)

Return the square of the maximum Euclidean distance that the robot will be from the origin.

测试样例

Example 1:

Input: commands = [4,-1,3], obstacles = []

Output: 25

Explanation: robot will go to (3, 4)

Example 2:

Input: commands = [4,-1,4,-2,4], obstacles = [[2,4]]

Output: 65

Explanation: robot will be stuck at (1, 4) before turning left and going to (1, 8)

Note:

0 <= commands.length <= 10000

0 <= obstacles.length <= 10000

-30000 <= obstacle[i][0] <= 30000

-30000 <= obstacle[i][1] <= 30000

The answer is guaranteed to be less than 2 ^ 31.

题解

题目要求在直角坐标系上有一个机器人——姑且看成一个点——在经过旋转、移动的时候,计算离原点最远的距离,算出该值的平方值。

从难度来看这是一个easy题,但是主要是因为测例主要是在小范围的,即使在极端情况下的样例,也没有达到最大的复杂度。

在一种可以AC的代码中,计算每一个移动操作在经过障碍的时候遍历障碍的时候使用的方法是加步长,而这个步长只是1。那么如果移动操作给出了10000(符合条件),则要执行10000次这样的操作,如果在坐标范围内做(0,0)开始的边长为10^4的正方形移动,复杂度至少为10^8,计算结果超时了。计算的复杂度包括了:查找障碍,用C++11的hash表降到O(1),但是遍历障碍的复杂度O (commands.length * obstacles.length)。

这道easy的题的解决方法这样做没问题,最优的解法也是这样做的,但并不能说它就能在极端情况最优了。比较复杂的做法是记录x轴障碍,y轴障碍的数组,在数组中用二分法找到位置的结果。处理极端情况比上一种做法快了上千倍。当然,二分法有C++的一个库,可以用来求上下界,lower_bound(x)返回数组中第一个>=x的位置(不存在则返回end),

和upper_bound(x)返回y, y-1的值>=x。

一味追求在leetcode的速度最快是不合理的,一些leetcode的样例并不能反映问题的复杂度。

代码

#include<bits/stdc++.h>
#include <unordered_set>
#define square(x, y) ((x * x) + (y * y))
#define MAXN 10010
using namespace std;
bool cmp(const vector<int>& a, const vector<int>& b) {
    if (a[0] == b[0]) {
        return a[1] < b[1];
    }
    return a[0] < b[0];
}
class Solution {
public:
    friend bool cmp(const vector<int>& a, const vector<int>& b);
    map<int, vector<int> > pix, piy;
    int maxdis;
    typedef map<int, vector<int> > mpv;
    typedef vector<int> vi;
    void setValid(int* curx,
        int* cury, int t, int command) {
        vector<int> vec;
        if (t == 0 || t == 2) {
            vec = pix[*curx];
        } else {
            vec = piy[*cury];
        }
        vi::iterator it;
        if (t == 0) {
            it = upper_bound(vec.begin(), vec.end(), *cury);
            if (it == vec.end() || vec.size() == 0) {
                *cury = *cury + command;
            } else {
                *cury = min(*it - 1, *cury + command);
            }
        } else if (t == 2) {
            it = lower_bound(vec.begin(), vec.end(), *cury);
            if (vec.size() == 0 || it == vec.begin()) {
                *cury = *cury - command;
            } else {
                *cury = max(*(it - 1) + 1, *cury - command);
            }
        } else if (t == 1) {
            it = upper_bound(vec.begin(), vec.end(), *curx);
            if (it == vec.end() || vec.size() == 0) {
                *curx = *curx + command;
            } else {
                *curx = min(*it - 1, *curx + command);
            }
        } else {
            it = lower_bound(vec.begin(), vec.end(), *curx);
            if (vec.size() == 0 || it == vec.begin()) {
                *curx = *curx - command;
            } else {
                *curx = max(*(it - 1) + 1, *curx - command);
            }
        }
    }

    int robotSim(vector<int>& commands, vector<vector<int> >& obstacles) {
        pix.clear();
        piy.clear();
        sort(obstacles.begin(), obstacles.end(), cmp);
        int tsize = 0;
        if (obstacles.size() > 0) {
            tsize = obstacles[0].size();
        }
        int dxy[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        int size = obstacles.size();
        int t = 0;
        int curx = 0, cury = 0;
        int obx, oby;
        int dis = 0;
        maxdis = 0; //max euclidean distance
        for (int i = 0; i < size; i++) {
            obx = obstacles[i][0];
            oby = obstacles[i][1];
            pix[obx].push_back(oby);
            piy[oby].push_back(obx);
        }
        #if 0
        cout << "x\n";
        for (mpv::iterator it = pix.begin(); it != pix.end(); ++it) {
            cout << it->first;
            for (int j = 0; j < it->second.size(); j++) {
                cout << " " << it->second[j];
            }
            cout << endl;
        }
        cout << "y\n";
        for (mpv::iterator it = piy.begin(); it != piy.end(); ++it) {
            cout << it->first;
            for (int j = 0; j < it->second.size(); j++) {
                cout << " " << it->second[j];
            }
            cout << endl;
        }
        #endif
        size = commands.size();
        for (int i = 0; i < size; i++) {
            if (commands[i] == -1) {
                t = (t + 1) % 4;
            }
            else if (commands[i] == -2) {
                t = (t - 1 + 4) % 4;
            } else {
                setValid(&curx, &cury, t, commands[i]);
                dis = square(curx, cury);
                if (dis > maxdis) {
                    maxdis = dis;
                }
            }
        }
        return maxdis;
    }
};

leetcode参考解

static auto __ = [] () {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return 0;
}();

#define HASH(x, y) (((unsigned long long)(x) << 32) | (unsigned int)(y))

class Solution {
public:

    int robotSim(vector<int>& commands, vector<vector<int> >& obstacles) {
        unordered_set<unsigned long long> obs_set;
        for(const auto & a: obstacles) {
            obs_set.insert(HASH(a[0], a[1]));
        }

        int max = 0;
        int x = 0;
        int y = 0;

        int* axis[] = {&y, &x, &y, &x};
        int diff[] = {1, 1, -1, -1};
        int direct = 0;

        for (const auto&c: commands) {
            if(c < 0) {
                // Turning left and turning right are opposite actions, it‘s good to be -1 and 1.
                direct += ((c + 1) << 1) + 1;
                direct &= 3;
                continue;
            }

            int &a = *axis[direct];
            int d = diff[direct];

            for(int i = 0; i < c; i++) {
                a += d;
                if (obs_set.end() != obs_set.find(HASH(x, y))) {
                    a -= d;
                    break;
                }
            }

            int distance = x * x + y * y;
            if(max < distance) {
                max = distance;
            }
        }

        return max;
    }
};

参考

theodoreyth. Walking Robot Simulation. https://leetcode.com/problems/walking-robot-simulation/description/. May,2018.

原文地址:https://www.cnblogs.com/wangzming/p/9787035.html

时间: 2024-11-08 15:55:15

leetcode 874 Robot Simulation的相关文章

[LeetCode] Walking Robot Simulation 走路机器人仿真

A robot on an infinite grid starts at point (0, 0) and faces north.? The robot can receive one of three possible types of commands: -2: turn left 90 degrees -1: turn right 90 degrees 1 <= x <= 9: move forward?x?units Some of the grid squares are obs

【Leetcode_easy】874. Walking Robot Simulation

problem 874. Walking Robot Simulation 参考 1. Leetcode_easy_874. Walking Robot Simulation; 完 原文地址:https://www.cnblogs.com/happyamyhope/p/11252142.html

874.Walking Robot Simulation(list不可被哈希)

A robot on an infinite grid starts at point (0, 0) and faces north. The robot can receive one of three possible types of commands: -2: turn left 90 degrees -1: turn right 90 degrees 1 <= x <= 9: move forward x units Some of the grid squares are obst

874. Walking Robot Simulation

A robot on an infinite grid starts at point (0, 0) and faces north.  The robot can receive one of three possible types of commands: -2: turn left 90 degrees -1: turn right 90 degrees 1 <= x <= 9: move forward x units Some of the grid squares are obs

[leetcode] 874. 行走机器人模拟(周赛)

874. 行走机器人模拟 模拟 class Solution { public int robotSim(int[] commands, int[][] obstacles) { int max = 0; int[][] dx = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int k = 0; Map<String, Boolean> map = new HashMap<>(); for (int i = 0; i < obstacles.len

[LeetCode] 489. Robot Room Cleaner 扫地机器人

Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or blocked. The robot cleaner with 4 given APIs can move forward, turn left or turn right. Each turn it made is 90 degrees. When it tries to move into a blocked cel

[Leetcode]657. Robot Return to Origin

Easy There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its moves, judge if this robot ends up at (0, 0) after it completes its moves. The move sequence is represented by a string, and the character moves[i]

【leetcode】Weekly Contest 94

题目不难,被第二题卡了半个多小时QAQ,另一个就是以后能用Hashmap和Hashset的绝不遍历. 1. Leaf-Similar Trees dfs.层次遍历把叶子节点遍历然后对比即可,只要是先遍历左节点后遍历右节点就行. 1 class Solution { 2 public boolean leafSimilar(TreeNode root1, TreeNode root2) { 3 ArrayList<Integer> res1 = new ArrayList<>();

【LeetCode】贪心 greedy(共38题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [44]Wildcard Matching [45]Jump Game II (2018年11月28日,算法群衍生题) 题目背景和 55 一样的,问我能到达最后一个index的话,最少走几步. 题解: [55]Jump Game (2018年11月27日,算法群) 给了一个数组nums,nums[i] = k 代表站在第 i 个位置的情况下, 我最多能往前走 k 个单