[剑指offer]机器人的运动范围
题目来源:牛客网
描述:
地上有一个rows行和cols列的方格。坐标从 [0,0] 到 [rows-1,cols-1]。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于threshold的格子。 例如,当threshold为18时,机器人能够进入方格[35,37],因为3+5+3+7 = 18。但是,它不能进入方格[35,38],因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
范围:
1 <= rows, cols<= 100
0 <= threshold <= 20
示例1
输入:
10,1,100
返回值:
29
说明:
[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13],[0,14],[0,15],[0,16],[0,17],[0,18],[0,19],[0,20],[0,21],[0,22],[0,23],[0,24],[0,25],[0,26],[0,27],[0,28] 这29种,后面的[0,29],[0,30]以及[0,31]等等是无法到达的
示例2
输入:
5,10,10
返回值:
21
解题思路:
方法一:DFS遍历、回溯。
根据题目描述,我们可以模拟题目,我们假设一个5x5
矩阵,阈值threshold=3,如果我们用DFS
的话,就相当于“不撞南墙不回头”,如图:
图片来源:牛客网。
因此我们只需要从(0,0)开始遍历,可向右向左向下,如果向右不满足条件后回溯到前一个状态,查看向下是否满足,为了防止重复计数某一个点,可先初始化一个矩阵用来存储该位置是否已经被遍历。以下是Python实现:
# -*- coding:utf-8 -*-
class Solution:
def __init__(self):
# 用于标记当前列状况,0代表没有记录过,1代表已经记录过
self.vector = [[0 for i in range(100)] for j in range(100)]
self.res = 0 # 用于记录答案
def movingCount(self, threshold, rows, cols):
self.dfs(0,0,rows,cols,threshold)
return self.res
def dfs(self,row,col,rows,cols,threshold):
"""使用深度优先算法遍历,递归搜索"""
if row > rows-1 or col > cols - 1:
return
if self.check_less(row, col, threshold) and self.vector[row][col]==0:
self.vector[row][col] = 1
self.res += 1
else:
return
self.dfs(row, col+1, rows, cols, threshold)
self.dfs(row+1, col, rows, cols, threshold)
def check_less(self,row,col,threshold):
"""判断是否能进入方格
row:当前需要判断的行
col:当前需要判断的列
return: bool
"""
sum= 0
while row:
sum += row % 10
row //= 10
while col:
sum += col % 10
col //= 10
if sum <=threshold:
return True
return False
方法二:BFS遍历
在更中