问题描述 链接到标题
2069. 模拟行走机器人 II (Medium)
给你一个在 XY 平面上的 width x height
的网格图, 左下角 的格子为 (0, 0)
, 右上角 的格子
为 (width - 1, height - 1)
。网格图中相邻格子为四个基本方向之一( "North"
, "East"
, "South"
和 "West"
)。一个机器人 初始 在格子 (0, 0)
,方向为 "East"
。
机器人可以根据指令移动指定的 步数 。每一步,它可以执行以下操作。
- 沿着当前方向尝试 往前一步 。
- 如果机器人下一步将到达的格子 超出了边界 ,机器人会 逆时针 转 90 度,然后再尝试往前一步。
如果机器人完成了指令要求的移动步数,它将停止移动并等待下一个指令。
请你实现 Robot
类:
Robot(int width, int height)
初始化一个width x height
的网格图,机器人初始在(0, 0)
,方向 朝"East"
。void step(int num)
给机器人下达前进num
步的指令。int[] getPos()
返回机器人当前所处的格子位置,用一个长度为 2 的数组[x, y]
表示。String getDir()
返回当前机器人的朝向,为"North"
,"East"
,"South"
或者"West"
。
示例 1:
输入:
["Robot", "step", "step", "getPos", "getDir", "step", "step", "step", "getPos", "getDir"]
[[6, 3], [2], [2], [], [], [2], [1], [4], [], []]
输出:
[null, null, null, [4, 0], "East", null, null, null, [1, 2], "West"]
解释:
Robot robot = new Robot(6, 3); // 初始化网格图,机器人在 (0, 0) ,朝东。
robot.step(2); // 机器人朝东移动 2 步,到达 (2, 0) ,并朝东。
robot.step(2); // 机器人朝东移动 2 步,到达 (4, 0) ,并朝东。
robot.getPos(); // 返回 [4, 0]
robot.getDir(); // 返回 "East"
robot.step(2); // 朝东移动 1 步到达 (5, 0) ,并朝东。
// 下一步继续往东移动将出界,所以逆时针转变方向朝北。
// 然后,往北移动 1 步到达 (5, 1) ,并朝北。
robot.step(1); // 朝北移动 1 步到达 (5, 2) ,并朝 北 (不是朝西)。
robot.step(4); // 下一步继续往北移动将出界,所以逆时针转变方向朝西。
// 然后,移动 4 步到 (1, 2) ,并朝西。
robot.getPos(); // 返回 [1, 2]
robot.getDir(); // 返回 "West"
提示:
2 <= width, height <= 100
1 <= num <= 10⁵
step
,getPos
和getDir
总共 调用次数不超过10⁴
次。
解题思路 链接到标题
这是一道有点麻烦的模拟题,但其实注意到两点就不难了:
- 机器人只会位于网格最外层的这一圈上;
- 我们可以记录机器人总共移动了多少步,这样就可以以 $(0, 0)$ 为起点进行计算,而不需要使用机器人的上一个位置;
代码 链接到标题
class Robot {
public:
Robot(int width, int height) {
wid_ = width;
hei_ = height;
}
void step(int num) {
total += num;
if (total == 0) {
return;
}
int realmove = total % (wid_ - 1 + hei_ - 1 + wid_ - 1 + hei_ - 1);
if (realmove == 0) {
direct = 3;
posx = 0;
posy = 0;
} else if (realmove > 0 && realmove <= wid_ - 1) {
direct = 0;
posx = realmove;
posy = 0;
} else if (realmove > wid_ - 1 && realmove <= wid_ - 1 + hei_ - 1) {
posx = wid_ - 1;
posy = realmove - (wid_ - 1);
direct = 1;
} else if (realmove > wid_ - 1 + hei_ - 1 && realmove <= wid_ - 1 + hei_ - 1 + wid_ - 1) {
posy = hei_ - 1;
posx = wid_ - 1 - (realmove - (wid_ - 1 + hei_ - 1));
direct = 2;
} else {
posx = 0;
posy = hei_ - 1 - (realmove - (wid_ - 1 + hei_ - 1 + wid_ - 1));
direct = 3;
}
}
vector<int> getPos() {
return {posx, posy};
}
string getDir() {
switch (direct % 4) {
case 0:
return "East";
case 1:
return "North";
case 2:
return "West";
case 3:
return "South";
}
return "";
}
private:
int posx = 0;
int posy = 0;
int direct = 0;
int wid_;
int hei_;
int total = 0;
};