题目
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
这是一个搜索问题,可以用深度优先搜索(DFS)和广度优先搜索(BFS)两种方法解决。
DFS
def movingCount(self, threshold, rows, cols):
move = [[0, 1], [1, 0]]
mark = [[0] * cols for _ in range(rows)]
def weisum(n):
t = 0
while n != 0:
t = t + n % 10
n = n // 10
return t
def back(x, y):
s = 0
if 0 <= x < rows and 0 <= y < cols and mark[x][y] == 0:
if weisum(x) + weisum(y) <= threshold:
mark[x][y] = 1
s=1
for i in range(len(move)):
s += back(x + move[i][0], y + move[i][1])
return s
return back(0, 0)
DFS是回溯算法,每次到达一个格子后分别向右向下继续搜索,遇到障碍就返回到前一个格子。这里要注意python不能传址,格子总数s只能用返回值的形式累加。
BFS
def movingCount(self, threshold, rows, cols):
def weisum(n):
t = 0
while n != 0:
t = t + n % 10
n = n // 10
return t
re = set()
que = []
que.append((0, 0))
while que:
temp = que.pop(0)
if temp not in re:
x,y=temp
if 0 <= x < rows and 0 <= y < cols and weisum(
x) + weisum(y) <= threshold:
re.add(temp)
que.append((x+1,y))
que.append((x,y+1))
return len(re)
BFS方法是用一个集合存储所有的格子坐标。先将(0,0)入队列,当队列不为空时,出队首元素,判断是否符合要求,符合则将该元素的右元素和下元素依次入队列。最后返回集合长度。
这里队列用的是list,也可以用python中的Queue类。