【Leetcode竞赛杯】LCP 03. 机器人大冒险

力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0)。小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动。指令有两种:

U: 向y轴正方向移动一格
R: 向x轴正方向移动一格。

不幸的是,在 xy 平面上还有一些障碍物,他们的坐标用obstacles表示。机器人一旦碰到障碍物就会被损毁。

给定终点坐标(x, y),返回机器人能否完好地到达终点。如果能,返回true;否则返回false。

示例 1:

输入:command = "URR", obstacles = [], x = 3, y = 2
输出:true
解释:U(0, 1) -> R(1, 1) -> R(2, 1) -> U(2, 2) -> R(3, 2)。

示例 2:

输入:command = "URR", obstacles = [[2, 2]], x = 3, y = 2
输出:false
解释:机器人在到达终点前会碰到(2, 2)的障碍物。

示例 3:

输入:command = "URR", obstacles = [[4, 2]], x = 3, y = 2
输出:true
解释:到达终点后,再碰到障碍物也不影响返回结果。

限制:

2 <= command的长度 <= 1000
command由U,R构成,且至少有一个U,至少有一个R
0 <= x <= 1e9, 0 <= y <= 1e9
0 <= obstacles的长度 <= 1000
obstacles[i]不为原点或者终点

思路

参考:机器人大冒险 - 解答
已知机器人在第一次循环中走过的所有点,和向右移动的总距离 dx,和向上移动的总距离 dy。给出任意一个点 (m,n),如何判断这个点是否在机器人的运动轨迹中?
我们可以计算出从原点到 (m,n)需要走多少个循环,也就是min(m/xx,n/yy)。然后我们就可以得到点 (m,n)相当于第一次循环中的哪个点。如果这个点在第一次循环的轨迹中,那么机器人一定可以到达这个点。反之则不能到达。

在本题中,机器人能够完好地到达终点需要满足两个条件:

  1. 终点一定在机器人运动的轨迹中(一定在第一次循环的轨迹中)
  2. 所有障碍物的坐标都不在机器人运动的轨迹中(一定不在第一次循环的轨迹中)
#include "bits/stdc++.h"
#include <unordered_set>
using namespace std;

class Solution {
public:
    bool robot(string command, vector<vector<int>>& obstacles, int x, int y) {
       unordered_set<long> us;
       int dx = 0;
       int dy = 0;
       us.insert(0); // (0 << 30 | 0) = 0
       for (const auto& ch : command) {
           if (ch == 'U') {
               ++dy;
           } else if (ch == 'R') {
               ++dx;
           }
           us.insert(((long)dx << 30) | dy);
       }

       int times = min(x / dx, y / dy); // 经历循环次数
       if (us.count(((long)(x - times * dx) << 30) | (y - times *dy)) == 0) {
           return false;
       }

       for (const auto& obstacle : obstacles) {
           if (obstacle[0] > x || obstacle[1] > y) {
               continue;
           }
           times = min(obstacle[0] / dx, obstacle[1]/ dy);
           if(us.count(((long)(obstacle[0] - times * dx) << 30) | (obstacle[1] - times * dy))) {
               return false;
           }
       }

       return true;
    }
};

在64位系统上,int是32位二进制表示,最大值为2147483647,是1e9的两倍之多,所以坐标x和y都在int范围内
Q:如何用一个64位的long/long long型整数代表int型的(x, y)坐标?
A:long z = (x << 32) | y,则z的高32位代表x,低32位代表y,z与(x, y)是一一映射的关系。
其实本题x和y都不超过1e9,1e9转成二进制约占30位(log(1e9) ≈ 30,所以左移30位就够了,用long型(大于60位)表示,左30位表示x,右30位表示y;
参考:使用位运算压缩坐标 (x, y) 的技巧以及背后原理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值