依题意,显然应该一步步模拟之
其中难解决的两个问题:
- 如何判断面对的是障碍点?
当然可以定义一个很大的二维数组,然后将障碍点记为1,但那样极其浪费内存
我们可以定义一个类型为pair的set,一开始将障碍点的坐标insert进set中,每走一步,判断面对的点是不是障碍点,若不是障碍点,则继续往前走,若是障碍点,则停下,等待转弯
我这里选择了unordered_set,需要注意自己重写一个哈希类
可以参考 https://blog.csdn.net/include_not_found_/article/details/104881974
- 如何实现左转右转?
可以用两个整数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;
}
};