地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1
输出:3
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
提示:
1 <= n,m <= 100
0 <= k <= 20
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof
这题很容易误解, 直接遍历整个二维数组,判断是否小于k,小于就说明满足条件 ,这样子做就不对了。
因为有些格子他的行坐标和列坐标的数位之和小于k,但是,机器人也到不了这里。因为机器人只能上下左右移动,有些满足小于k的格子被挡住了。
看到 上、下、左、右 四个方向就要马上想到搜索,这题是一道比较典型的搜索题目。
class Solution {
private:
int movDistance[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
int flag[101][101] = {0};
int ans = 0;
void dfs(int x, int y, int m, int n, int k) {
flag[x][y] = 1;
for (int i = 0; i < 4; ++i) {
int mx = x + movDistance[i][0], my = y + movDistance[i][1];
if (0 <= mx && mx < m && 0 <= my && my < n && !flag[mx][my] && sum(mx, my) <= k) {
++ans;
dfs(mx, my, m, n, k);
}
}
}
int sum(int x, int y) {
return (x % 10 + x / 10) + (y % 10 + y / 10); // 因为题目说了0 <= n, m <= 100, 所以这里简化写法了。
}
public:
int movingCount(int m, int n, int k) {
dfs(0, 0, m, n, k);
return ans + 1;
}
};
class Solution:
def __init__(self):
self.ans = 0
self.mvDistance = [[-1, 0], [1, 0], [0, -1], [0, 1]]
self.flag = [[0] * 101 for i in range(102)]
def movingCount(self, m: int, n: int, k: int) -> int:
def my_sum(x, y):
return (x // 10 + x % 10) + (y // 10 + y % 10)
def dfs(x, y, m, n, k):
self.flag[x][y] = 1
for i in range(4):
mx, my = x + self.mvDistance[i][0], y + self.mvDistance[i][1]
if 0 <= mx < m and 0 <= my < n and not self.flag[mx][my] and my_sum(mx, my) <= k:
self.ans += 1
dfs(mx, my, m, n, k)
dfs(0, 0, m, n, k)
return self.ans + 1
搜索之类的题目,基本上都是有模板可以套的,千万不要去人肉递归,这样之会越搞越糊涂,要是不理解,画个递归树还是可以的。真正掌握这种题,还是要多刷,刷多了就有感觉了。