1. 题目链接:LCR 130. 衣橱整理
2. 题目描述:
家居整理师将待整理衣橱划分为
m x n
的二维矩阵grid
,其中grid[i][j]
代表一个需要整理的格子。整理师自grid[0][0]
开始 逐行逐列 地整理每个格子。整理规则为:在整理过程中,可以选择 向右移动一格 或 向下移动一格,但不能移动到衣柜之外。同时,不需要整理
digit(i) + digit(j) > cnt
的格子,其中digit(x)
表示数字x
的各数位之和。请返回整理师 总共需要整理多少个格子。
示例 1:
输入:m = 4, n = 7, cnt = 5 输出:18
提示:
1 <= n, m <= 100
0 <= cnt <= 20
3. 算法思路:
这是一道非常典型的搜索类问题
我们可以通过深搜或者宽搜,从[0,0]
点出发,按照题目的规则一直往[m-1,n-1]
位置走,
同时设置一个全局变量,每次走到一个合法的位置,就将全局变量加1,当我们把所有走到的路都走完之后,全局变量里存的就是最终答案
4. 算法流程:
-
定义变量和数组:在类
Solution
中,定义了以下成员变量和数组:m
、n
、cnt
:分别表示矩阵的行数、列数和计数器。vis
:布尔数组,用于记录每个位置是否被访问过。ret
:整数变量,用于记录结果。dx
和dy
:两个整数数组,分别表示上下左右四个方向的偏移量。
-
函数
wardrobeFinishing
:这是算法的主函数,接收三个参数:矩阵的行数_m
、列数_n
和计数器_cnt
。它的作用是调用深度优先搜索算法来解决问题,并返回结果。- 将参数赋值给成员变量
m
、n
和cnt
。 - 调用
dfs(0, 0)
从矩阵的第一个位置开始进行深度优先搜索。 - 返回结果
ret
。
- 将参数赋值给成员变量
-
函数
dfs
:这是一个递归函数,用于执行深度优先搜索。它接收两个参数:当前位置的行坐标i
和列坐标j
。- 将结果
ret
加1。 - 标记当前位置为已访问。
- 遍历四个方向(上、下、左、右),计算下一个位置的坐标。
- 如果下一个位置在矩阵范围内且未被访问过且满足条件(通过调用
check(x, y)
函数判断),则继续递归调用dfs(x, y)
进行深度优先搜索。
- 将结果
-
函数
check
:这是一个辅助函数,用于检查给定位置是否满足特定条件。它接收两个参数:当前位置的行坐标i
和列坐标j
。- 初始化变量
tmp
为0,用于存储数字之和。 - 使用循环,当
i
不为0时,执行以下操作:- 将
i
的个位数加入tmp
。 - 将
i
除以10,去掉个位数。
- 将
- 使用循环,当
j
不为0时,执行以下操作:- 将
j
的个位数加入tmp
。 - 将
j
除以10,去掉个位数。
- 将
- 判断
tmp
是否小于等于计数器cnt
,如果是则返回true,否则返回false。
- 初始化变量
这个算法的目的是通过深度优先搜索遍历矩阵中的每个位置,并根据特定条件进行判断和处理。最终的结果存储在变量ret
中,并通过函数wardrobeFinishing
返回。
5. C++算法代码:
class Solution {int m, n, cnt; // 定义变量m、n、cnt,分别表示矩阵的行数、列数和计数器bool vis[101][101]; // 定义布尔数组vis,用于记录每个位置是否被访问过int ret; // 定义变量ret,用于记录结果int dx[4] = {0, 0, 1, -1}; // 定义数组dx,表示上下左右四个方向的偏移量int dy[4] = {1, -1, 0, 0}; // 定义数组dy,表示上下左右四个方向的偏移量public:int wardrobeFinishing(int _m, int _n, int _cnt) { // 定义函数wardrobeFinishing,接收三个参数:矩阵的行数、列数和计数器m = _m, n = _n, cnt = _cnt; // 将参数赋值给成员变量dfs(0, 0); // 从矩阵的第一个位置开始进行深度优先搜索return ret; // 返回结果}void dfs(int i, int j) { // 定义函数dfs,接收两个参数:当前位置的行坐标和列坐标ret++; // 结果加1vis[i][j] = true; // 标记当前位置为已访问for (int k = 0; k < 4; k++) { // 遍历四个方向int x = i + dx[k], y = j + dy[k]; // 计算下一个位置的坐标if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && check(x, y)) { // 如果下一个位置在矩阵范围内且未被访问过且满足条件dfs(x, y); // 继续深度优先搜索}}}bool check(int i, int j) { // 定义函数check,接收两个参数:当前位置的行坐标和列坐标int tmp = 0; // 定义变量tmp,用于存储数字之和while (i) { // 当i不为0时,执行循环tmp += i % 10; // 将i的个位数加入tmpi /= 10; // i除以10,去掉个位数}while (j) { // 当j不为0时,执行循环tmp += j % 10; // 将j的个位数加入tmpj /= 10; // j除以10,去掉个位数}return tmp <= cnt; // 判断tmp是否小于等于计数器,如果是则返回true,否则返回false}
};