剑指13:机器人的运动范围

传送门

nowcoder
leetcode

题目描述

地上有一个 m 行 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,
每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。
例如,当 k 为 18 时,机器人能够进入方格 (35, 37),因为 3+5+3+7 = 18 。
但是,它不能进入方格 (35, 38),因为 3+5+3+8 = 19 。
请问该机器人能够达到多少个格子?

C++ 代码 - nowcoder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
递归
*/
class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
if (rows < 0 || cols < 0) return 0;

vector<vector<bool>> visited(rows, vector<bool>(cols, false));
return movingCountCore(threshold, rows, cols, visited, 0, 0);
}

int movingCountCore(int threshold, int rows, int cols,
vector<vector<bool>> &visited, int i, int j)
{
if (i < 0 || i >= rows || j < 0 || j >= cols
|| !canReach(threshold, i, j) || visited[i][j] == true)
return 0;

visited[i][j] = true;
// 上右下左
return movingCountCore(threshold, rows, cols, visited, i - 1, j)
+ movingCountCore(threshold, rows, cols, visited, i, j + 1)
+ movingCountCore(threshold, rows, cols, visited, i + 1, j)
+ movingCountCore(threshold, rows, cols, visited, i, j - 1)
+ 1;
}

bool canReach(int threshold, int x, int y) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
while (y > 0) {
sum += y % 10;
y /= 10;
}
return sum <= threshold;
}
};

/*
BFS
*/
class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
if (rows < 0 || cols < 0) return 0;

vector<vector<bool>> visited(rows, vector<bool>(cols, false));
queue<pair<int, int>> q;
q.push(make_pair(0, 0));
visited[0][0] = true;

int dx[] = { -1, 0, 1, 0 }, dy[] = { 0, 1, 0, -1 }; // 上右下左
int cnt = 0;
while (!q.empty()) {
cnt ++;
// int x, y;
// tie(x, y) = q.front();
int x = q.front().first, y = q.front().second;
q.pop();
for (int i = 0; i < 4; i ++) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < rows && b >= 0 && b < cols
&& !visited[a][b] && canReach(threshold, a, b)) {
q.push(make_pair(a, b));
visited[a][b] = true;
}
}
}
return cnt;
}

bool canReach(int threshold, int x, int y) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
while (y > 0) {
sum += y % 10;
y /= 10;
}
return sum <= threshold;
}
};

C++ 代码 - leetcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
递归
*/
class Solution {
public:
int movingCount(int m, int n, int k) {
if (m < 0 || n < 0) return 0;

vector<vector<bool>> visited(m, vector<bool>(n, false));
return dfs(m, n, k, visited, 0, 0);
}

int dfs(int rows, int cols, int threshold,
vector<vector<bool>> &visited, int i, int j) {
if (i < 0 || i >= rows || j < 0 || j >= cols || !canReach(i, j, threshold) || visited[i][j]) {
return 0;
}

visited[i][j] = true;
// 上右下左
return dfs(rows, cols, threshold, visited, i - 1, j)
+ dfs(rows, cols, threshold, visited, i, j + 1)
+ dfs(rows, cols, threshold, visited, i + 1, j)
+ dfs(rows, cols, threshold, visited, i, j - 1) + 1;
}

bool canReach(int x, int y, int threshold) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
while (y > 0) {
sum += y % 10;
y /= 10;
}
return sum <= threshold;
}
};

/*
BFS
*/
class Solution {
public:
int movingCount(int m, int n, int k) {
if (m < 0 || n < 0) return 0;

vector<vector<bool>> visited(m, vector<bool>(n, false));
queue<pair<int, int>> q;
q.push(make_pair(0, 0));
visited[0][0] = true;

int dx[] = { -1, 0, 1, 0 }, dy[] = { 0, 1, 0, -1 }; // 上右下左
int cnt = 0;
while (!q.empty()) {
// int x, y;
// tie(x, y) = q.front();
int x = q.front().first, y = q.front().second;
q.pop();
cnt ++;
for (int i = 0; i < 4; i ++) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < m && b >= 0 && b < n
&& !visited[a][b] && canReach(a, b, k)) {
q.push(make_pair(a, b));
visited[a][b] = true;
}
}
}
return cnt;
}

bool canReach(int x, int y, int threshold) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
while (y > 0) {
sum += y % 10;
y /= 10;
}
return sum <= threshold;
}
};

剑指13:机器人的运动范围
https://lcf163.github.io/2021/01/29/剑指13:机器人的运动范围/
作者
乘风的小站
发布于
2021年1月29日
许可协议