@@ -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
115220class 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