leetcode 2069. 模拟行走机器人 II 中等

给你一个在 XY 平面上的 width x height 的网格图,左下角 的格子为 (0, 0)右上角 的格子为 (width - 1, height - 1) 。网格图中相邻格子为四个基本方向之一("North""East""South""West")。一个机器人 初始 在格子 (0, 0) ,方向为 "East"

机器人可以根据指令移动指定的 步数 。每一步,它可以执行以下操作。

  1. 沿着当前方向尝试 往前一步
  2. 如果机器人下一步将到达的格子 超出了边界 ,机器人会 逆时针 转 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^5
  • stepgetPosgetDir 总共 调用次数不超过 10^4 次。

分析:用一个数字变量 dir 表示移动的方向,0~3 分别代表西、北、东、南。顺时针移动时 dir++,逆时针移动时 dir--。每次移动时,首先对周长取模,再看当前移动是否会出界,如果会出界,则先移动到边界,再改变方向,接着继续走,否则方向不变,走到对应的位置。在实现上,可以先走 n-1 步,再走一步,避免方向计算错误的问题。

cpp 复制代码
typedef struct {
    int width,height,pos_x,pos_y,dir;
} Robot;


Robot* robotCreate(int width, int height) {
    Robot *r=(Robot*)malloc(sizeof(Robot));
    r->width=width,r->height=height,r->pos_x=0,r->pos_y=0,r->dir=1;
    return r;
}

void robotStep(Robot* obj, int num) {
    int t=0,len=obj->width*2+obj->height*2-4;num=(num-1)%len;
    while(num)
    {
        if(obj->dir==0)
        {
            if(obj->pos_y+num>=obj->height)num-=obj->height-1-obj->pos_y,obj->pos_y=obj->height-1,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_y+=num,num=0;
        }
        else if(obj->dir==1)
        {
            if(obj->pos_x+num>=obj->width)num-=obj->width-1-obj->pos_x,obj->pos_x=obj->width-1,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_x+=num,num=0;
        }
        else if(obj->dir==2)
        {
            if(obj->pos_y-num<0)num-=obj->pos_y,obj->pos_y=0,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_y-=num,num=0;
        }
        else if(obj->dir==3)
        {
            if(obj->pos_x-num<0)num-=obj->pos_x,obj->pos_x=0,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_x-=num,num=0;
        }
    }
    num=1;
    while(num)
    {
        if(obj->dir==0)
        {
            if(obj->pos_y+num>=obj->height)num-=obj->height-1-obj->pos_y,obj->pos_y=obj->height-1,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_y+=num,num=0;
        }
        else if(obj->dir==1)
        {
            if(obj->pos_x+num>=obj->width)num-=obj->width-1-obj->pos_x,obj->pos_x=obj->width-1,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_x+=num,num=0;
        }
        else if(obj->dir==2)
        {
            if(obj->pos_y-num<0)num-=obj->pos_y,obj->pos_y=0,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_y-=num,num=0;
        }
        else if(obj->dir==3)
        {
            if(obj->pos_x-num<0)num-=obj->pos_x,obj->pos_x=0,obj->dir=(obj->dir-1+4)%4;
            else obj->pos_x-=num,num=0;
        }
    }
}

int* robotGetPos(Robot* obj, int* retSize) {
    int *ans=(int*)malloc(sizeof(int)*2);
    *retSize=2;
    ans[0]=obj->pos_x,ans[1]=obj->pos_y;
    return ans;
}

char* robotGetDir(Robot* obj) {
    char *ss=(char*)malloc(sizeof(char)*10);
    if(obj->dir==0)ss=strcpy(ss,"North");
    else if(obj->dir==1)ss=strcpy(ss,"East");
    else if(obj->dir==2)ss=strcpy(ss,"South");
    else if(obj->dir==3)ss=strcpy(ss,"West");
    return ss;
}

void robotFree(Robot* obj) {
    free(obj);
    return;
}

/**
 * Your Robot struct will be instantiated and called as such:
 * Robot* obj = robotCreate(width, height);
 * robotStep(obj, num);
 
 * int* param_2 = robotGetPos(obj, retSize);
 
 * char* param_3 = robotGetDir(obj);
 
 * robotFree(obj);
*/
相关推荐
北顾笙9803 小时前
day24-数据结构力扣
数据结构·算法·leetcode
圣保罗的大教堂4 小时前
leetcode 2087. 网格图中机器人回家的最小代价 中等
leetcode
吃着火锅x唱着歌4 小时前
LeetCode 678.有效的括号字符串
算法·leetcode·职场和发展
圣保罗的大教堂6 小时前
leetcode 874. 模拟行走机器人 中等
leetcode
剑挑星河月7 小时前
394.字符串解码
数据结构·算法·leetcode
圣保罗的大教堂7 小时前
leetcode 3653. 区间乘法查询后的异或 I 中等
leetcode
圣保罗的大教堂7 小时前
leetcode 1848. 到目标元素的最小距离 简单
leetcode
YuanDaima20487 小时前
队列与单调队列基础原理与题目说明
人工智能·python·算法·leetcode·队列·手撕代码
Tisfy8 小时前
LeetCode 2515.到目标字符串的最短距离:从中间往两边遍历
算法·leetcode·字符串·题解·数组·遍历