2022-02-15:扫地机器人。 房间(用格栅表示)中有一个扫地机器人。 格栅中的每一个格子有空和障碍物两种可能。 扫地机器人提供4个API,可以向前进,向左转或者向右转。每次转弯90度。 当扫地机器人试图进入障碍物格子时,它的碰撞传感器会探测出障碍物,使它停留在原地。 请利用提供的4个API编写让机器人清理整个房间的算法。 interface Robot { // 若下一个方格为空,则返回true,并移动至该方格 // 若下一个方格为障碍物,则返回false,并停留在原地 boolean move();
// 在调用turnLeft/turnRight后机器人会停留在原位置 // 每次转弯90度 void turnLeft(); void turnRight();
// 清理所在方格 void clean(); } 输入: room = [ [1,1,1,1,1,0,1,1], [1,1,1,1,1,0,1,1], [1,0,1,1,1,1,1,1], [0,0,0,1,0,0,0,0], [1,1,1,1,1,1,1,1] ], row = 1, col = 3
解析: 房间格栅用0或1填充。0表示障碍物,1表示可以通过。 机器人从row=1,col=3的初始位置出发。在左上角的一行以下,三列以右。
注意: 输入只用于初始化房间和机器人的位置。你需要“盲解”这个问题。 换而言之,你必须在对房间和机器人位置一无所知的情况下,只使用4个给出的API解决问题。 扫地机器人的初始位置一定是空地。 扫地机器人的初始方向向上。 所有可抵达的格子都是相连的,亦即所有标记为1的格子机器人都可以抵达。 可以假定格栅的四周都被墙包围。 力扣489。
答案2022-02-15:
map记录走过的路。 0上,1右,2下,3左。 递归。
代码用golang编写。代码如下:
package main
import "strconv"
func main() {
}
// 不要提交这个接口的内容
type Robot interface {
move() bool
turnLeft()
turnRight()
clean()
}
// 提交下面的内容
func cleanRoom(robot Robot) {
clean(robot, 0, 0, 0, make(map[string]struct{}))
}
var ds = [][]int{{-1, 0}, {0, 1}, {1, 0}, {0, -1}}
// 机器人robot,
// 当前来到的位置(x,y),且之前没来过
// 机器人脸冲什么方向d,0 1 2 3
// visited里记录了机器人走过哪些位置
// 函数的功能:不要重复走visited里面的位置,把剩下的位置,都打扫干净!
// 而且要回去!
func clean(robot Robot, x, y, d int, visited map[string]struct{}) {
robot.clean()
visited[strconv.Itoa(x)+"_"+strconv.Itoa(y)] = struct{}{}
for i := 0; i < 4; i++ {
// d = 0 : 0 1 2 3
// d = 1 : 1 2 3 0
// d = 2 : 2 3 0 1
// d = 3 : 3 0 1 2
// 下一步的方向!
nd := (i + d) % 4
// 当下一步的方向定了!下一步的位置在哪?(nx, ny)
nx := ds[nd][0] + x
ny := ds[nd][1] + y
_, ok := visited[strconv.Itoa(nx)+"_"+strconv.Itoa(ny)]
if !ok && robot.move() {
clean(robot, nx, ny, nd, visited)
}
robot.turnRight()
}
// 负责回去:之前的位置,怎么到你的!你要回去,而且方向和到你之前,要一致!
robot.turnRight()
robot.turnRight()
robot.move()
robot.turnRight()
robot.turnRight()
}