Skip to content

Commit 1529bbf

Browse files
authored
feat: add solutions for lc No.2069 (#5141)
1 parent 635421d commit 1529bbf

7 files changed

Lines changed: 873 additions & 74 deletions

File tree

solution/2000-2099/2069.Walking Robot Simulation II/README.md

Lines changed: 294 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -85,75 +85,332 @@ robot.getDir(); // 返回 "West"
8585

8686
<!-- solution:start -->
8787

88-
### 方法一
88+
### 方法一:分类讨论
89+
90+
我们记 $mx = width - 1$ 和 $my = height - 1$,则机器人的运动轨迹是一个以 $(0, 0)$ 为左下角,而 $(mx, my)$ 为右上角的矩形的边界。我们可以将机器人的运动轨迹分为四段:
91+
92+
1. 从 $(0, 0)$ 沿着 $x$ 轴正方向运动到 $(mx, 0)$,此时机器人的朝向为 "East"。
93+
2. 从 $(mx, 0)$ 沿着 $y$ 轴正方向运动到 $(mx, my)$,此时机器人的朝向为 "North"。
94+
3. 从 $(mx, my)$ 沿着 $x$ 轴负方向运动到 $(0, my)$,此时机器人的朝向为 "West"。
95+
4. 从 $(0, my)$ 沿着 $y$ 轴负方向运动到 $(0, 0)$,此时机器人的朝向为 "South"。
96+
97+
因此,我们可以将机器人的运动轨迹看作是一个长度为 $p = 2 \cdot mx + 2 \cdot my$ 的循环。对于每次调用 `step(num)`,我们可以将机器人的当前位置加上 `num`,然后对 $p$ 取模,得到机器人的新位置。根据机器人的新位置,我们可以判断出机器人的朝向和坐标。
98+
99+
注意,如果机器人没有移动过,那么它的朝向应该是 "East"。如果机器人移动过,且位置为 $(0, 0)$,则机器人的朝向应该是 "South"。
100+
101+
时间复杂度 $O(1)$,空间复杂度 $O(1)$。
89102

90103
<!-- tabs:start -->
91104

92105
#### Python3
93106

94107
```python
95-
108+
class Robot:
109+
110+
def __init__(self, width: int, height: int):
111+
self.mx = width - 1
112+
self.my = height - 1
113+
self.p = 2 * self.mx + 2 * self.my
114+
self.cur = 0
115+
self.moved = False
116+
117+
def step(self, num: int) -> None:
118+
self.moved = True
119+
self.cur = (self.cur + num) % self.p
120+
121+
def getPos(self) -> List[int]:
122+
d = self.cur
123+
mx, my = self.mx, self.my
124+
if 0 <= d <= mx:
125+
return [d, 0]
126+
if mx < d <= mx + my:
127+
return [mx, d - mx]
128+
if mx + my < d <= 2 * mx + my:
129+
return [mx - (d - (mx + my)), my]
130+
return [0, my - (d - (2 * mx + my))]
131+
132+
def getDir(self) -> str:
133+
d = self.cur
134+
mx, my = self.mx, self.my
135+
if not self.moved:
136+
return "East"
137+
if 1 <= d <= mx:
138+
return "East"
139+
elif mx < d <= mx + my:
140+
return "North"
141+
elif mx + my < d <= 2 * mx + my:
142+
return "West"
143+
return "South"
144+
145+
146+
# Your Robot object will be instantiated and called as such:
147+
# obj = Robot(width, height)
148+
# obj.step(num)
149+
# param_2 = obj.getPos()
150+
# param_3 = obj.getDir()
96151
```
97152

98153
#### Java
99154

100155
```java
156+
class Robot {
101157

158+
private int mx, my, p, cur;
159+
private boolean moved;
160+
161+
public Robot(int width, int height) {
162+
this.mx = width - 1;
163+
this.my = height - 1;
164+
this.p = 2 * this.mx + 2 * this.my;
165+
this.cur = 0;
166+
this.moved = false;
167+
}
168+
169+
public void step(int num) {
170+
this.moved = true;
171+
this.cur = (this.cur + num) % this.p;
172+
}
173+
174+
public int[] getPos() {
175+
int d = this.cur;
176+
int mx = this.mx, my = this.my;
177+
178+
if (0 <= d && d <= mx) {
179+
return new int[] {d, 0};
180+
}
181+
if (mx < d && d <= mx + my) {
182+
return new int[] {mx, d - mx};
183+
}
184+
if (mx + my < d && d <= 2 * mx + my) {
185+
return new int[] {mx - (d - (mx + my)), my};
186+
}
187+
return new int[] {0, my - (d - (2 * mx + my))};
188+
}
189+
190+
public String getDir() {
191+
int d = this.cur;
192+
int mx = this.mx, my = this.my;
193+
194+
if (!this.moved) {
195+
return "East";
196+
}
197+
if (1 <= d && d <= mx) {
198+
return "East";
199+
} else if (mx < d && d <= mx + my) {
200+
return "North";
201+
} else if (mx + my < d && d <= 2 * mx + my) {
202+
return "West";
203+
}
204+
return "South";
205+
}
206+
}
207+
208+
/**
209+
* Your Robot object will be instantiated and called as such:
210+
* Robot obj = new Robot(width, height);
211+
* obj.step(num);
212+
* int[] param_2 = obj.getPos();
213+
* String param_3 = obj.getDir();
214+
*/
102215
```
103216

104217
#### C++
105-
#pragma GCC optimize("Ofast,unroll-loops,inline")
106-
#include <vector>
107-
#include <string>
108-
109-
static const int speedup = []() {
110-
std::ios_base::sync_with_stdio(false);
111-
std::cin.tie(NULL);
112-
return 0;
113-
}();
114218

219+
```cpp
115220
class Robot {
116-
int w, h, p, curr;
221+
public:
222+
int mx, my, p, cur;
117223
bool moved;
118-
// Используем массив строк, чтобы обращаться по индексу (0-3) без if-else
119-
const std::string dirs[4] = {"East", "North", "West", "South"};
120224

121-
public:
122-
Robot(int width, int height) : w(width), h(height), curr(0), moved(false) {
123-
p = (w + h - 2) << 1;
225+
Robot(int width, int height) {
226+
mx = width - 1;
227+
my = height - 1;
228+
p = 2 * mx + 2 * my;
229+
cur = 0;
230+
moved = false;
124231
}
125-
126-
inline void step(int num) {
232+
233+
void step(int num) {
127234
moved = true;
128-
curr = (curr + num) % p;
235+
cur = (cur + num) % p;
129236
}
130-
131-
inline std::vector<int> getPos() {
132-
if (curr < w) return {curr, 0};
133-
if (curr < w + h - 1) return {w - 1, curr - w + 1};
134-
if (curr < (w << 1) + h - 2) return { (w << 1) + h - 3 - curr, h - 1};
135-
return {0, p - curr};
237+
238+
vector<int> getPos() {
239+
int d = cur;
240+
int mx = this->mx, my = this->my;
241+
242+
if (0 <= d && d <= mx) {
243+
return {d, 0};
244+
}
245+
if (mx < d && d <= mx + my) {
246+
return {mx, d - mx};
247+
}
248+
if (mx + my < d && d <= 2 * mx + my) {
249+
return {mx - (d - (mx + my)), my};
250+
}
251+
return {0, my - (d - (2 * mx + my))};
136252
}
137-
138-
inline std::string getDir() {
139-
if (!moved) return dirs[0];
140-
if (curr == 0) return dirs[3]; // Робот вернулся в начало — всегда South
141-
142-
// Математическое определение направления без тяжелых веток
143-
if (curr < w) return dirs[0];
144-
if (curr < w + h - 1) return dirs[1];
145-
if (curr < (w << 1) + h - 2) return dirs[2];
146-
return dirs[3];
253+
254+
string getDir() {
255+
int d = cur;
256+
int mx = this->mx, my = this->my;
257+
258+
if (!moved) {
259+
return "East";
260+
}
261+
if (1 <= d && d <= mx) {
262+
return "East";
263+
} else if (mx < d && d <= mx + my) {
264+
return "North";
265+
} else if (mx + my < d && d <= 2 * mx + my) {
266+
return "West";
267+
}
268+
return "South";
147269
}
148270
};
149-
```cpp
150271

272+
/**
273+
* Your Robot object will be instantiated and called as such:
274+
* Robot* obj = new Robot(width, height);
275+
* obj->step(num);
276+
* vector<int> param_2 = obj->getPos();
277+
* string param_3 = obj->getDir();
278+
*/
151279
```
152280
153281
#### Go
154282
155283
```go
284+
type Robot struct {
285+
mx, my, p, cur int
286+
moved bool
287+
}
288+
289+
func Constructor(width int, height int) Robot {
290+
mx := width - 1
291+
my := height - 1
292+
return Robot{
293+
mx: mx,
294+
my: my,
295+
p: 2*mx + 2*my,
296+
cur: 0,
297+
moved: false,
298+
}
299+
}
300+
301+
func (this *Robot) Step(num int) {
302+
this.moved = true
303+
this.cur = (this.cur + num) % this.p
304+
}
305+
306+
func (this *Robot) GetPos() []int {
307+
d := this.cur
308+
mx, my := this.mx, this.my
309+
310+
if 0 <= d && d <= mx {
311+
return []int{d, 0}
312+
}
313+
if mx < d && d <= mx+my {
314+
return []int{mx, d - mx}
315+
}
316+
if mx+my < d && d <= 2*mx+my {
317+
return []int{mx - (d - (mx + my)), my}
318+
}
319+
return []int{0, my - (d - (2*mx + my))}
320+
}
321+
322+
func (this *Robot) GetDir() string {
323+
d := this.cur
324+
mx, my := this.mx, this.my
325+
326+
if !this.moved {
327+
return "East"
328+
}
329+
if 1 <= d && d <= mx {
330+
return "East"
331+
} else if mx < d && d <= mx+my {
332+
return "North"
333+
} else if mx+my < d && d <= 2*mx+my {
334+
return "West"
335+
}
336+
return "South"
337+
}
338+
339+
/**
340+
* Your Robot object will be instantiated and called as such:
341+
* obj := Constructor(width, height);
342+
* obj.Step(num);
343+
* param_2 := obj.GetPos();
344+
* param_3 := obj.GetDir();
345+
*/
346+
```
347+
348+
#### TypeScript
156349

350+
```ts
351+
class Robot {
352+
private mx: number;
353+
private my: number;
354+
private p: number;
355+
private cur: number;
356+
private moved: boolean;
357+
358+
constructor(width: number, height: number) {
359+
this.mx = width - 1;
360+
this.my = height - 1;
361+
this.p = 2 * this.mx + 2 * this.my;
362+
this.cur = 0;
363+
this.moved = false;
364+
}
365+
366+
step(num: number): void {
367+
this.moved = true;
368+
this.cur = (this.cur + num) % this.p;
369+
}
370+
371+
getPos(): number[] {
372+
const d = this.cur;
373+
const mx = this.mx,
374+
my = this.my;
375+
376+
if (0 <= d && d <= mx) {
377+
return [d, 0];
378+
}
379+
if (mx < d && d <= mx + my) {
380+
return [mx, d - mx];
381+
}
382+
if (mx + my < d && d <= 2 * mx + my) {
383+
return [mx - (d - (mx + my)), my];
384+
}
385+
return [0, my - (d - (2 * mx + my))];
386+
}
387+
388+
getDir(): string {
389+
const d = this.cur;
390+
const mx = this.mx,
391+
my = this.my;
392+
393+
if (!this.moved) {
394+
return 'East';
395+
}
396+
if (1 <= d && d <= mx) {
397+
return 'East';
398+
} else if (mx < d && d <= mx + my) {
399+
return 'North';
400+
} else if (mx + my < d && d <= 2 * mx + my) {
401+
return 'West';
402+
}
403+
return 'South';
404+
}
405+
}
406+
407+
/**
408+
* Your Robot object will be instantiated and called as such:
409+
* var obj = new Robot(width, height)
410+
* obj.step(num)
411+
* var param_2 = obj.getPos()
412+
* var param_3 = obj.getDir()
413+
*/
157414
```
158415

159416
<!-- tabs:end -->

0 commit comments

Comments
 (0)