第13题:机器人的运动范围
题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
考点:回溯法
1.从(0,0)开始走,每成功走一步标记当前位置为true,然后从当前位置往四个方向探索,
返回1 + 4 个方向的探索值之和。
2.探索时,判断当前节点是否可达的标准为:
1)当前节点在矩阵内;
2)当前节点未被访问过;
3)当前节点满足limit限制。
思路
//1.计数函数int,参数:阈值int,矩阵行数int,矩阵列数int,返回值:计数int
//1.1如果阈值为负,矩阵不存在,返回0
//1.2分配访问矩阵bool并初始化
//1.3初始化计数为0
//1.4 从(0,0)开始计数
//1.5返回计数
//2.搜索函数int ,参数:阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:计数int
//2.1 初始计数为0
//2.2 如果该位置满足条件
//2.2.1 更新访问矩阵
//2.2.2 从该位置的上下左右开始作为起点依次行递归调用,这里是计数,所以用+,如果是找存在路径就用或。
//2.3 返回计数
//3.匹配函数bool,参数::阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:是否满足条件 bool
//3.1 如果该位置满足条件:1.不越界。2.不超过阈值。3.未曾访问过。则返回真。
//3.2 否则返回假。
//4. 计算数位之和函数int,参数:数字int,返回值:数位之和int。
//4.1 初始化数为之和为0
//4.2 循环
//4.2.1 取余,先加个位数
//4.2.2 除以10,降一位
//4.3 返回sum
class Solution {
public:
//1.计数函数int,参数:阈值int,矩阵行数int,矩阵列数int,返回值:计数int
int movingCount(int threshold, int rows, int cols)
{
//1.1如果阈值为负,矩阵不存在,返回0
if(threshold<0||rows<0||cols<0)
return 0;
//1.2分配访问矩阵bool并初始化
bool* visited=new bool[rows*cols];
memset(visited,0,rows*cols);
//1.3初始化计数为0
int count=0;
//1.4 从(0,0)开始计数
count= movingCountCore(threshold,rows,cols,0,0,visited);
//返回计数
return count;
}
//2.搜索函数int ,参数:阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:计数int
int movingCountCore(int threshold,int rows,int cols,int row,int col,bool* visited)
{
//2.1 初始计数为0
int count=0;
//2.2 如果该位置满足条件
if(check(threshold,rows,cols,row,col,visited))
{
//2.2.1 更新访问矩阵
visited[row*cols+col]=true;
//2.2.2 从该位置的上下左右开始作为起点依次行递归调用,这里是计数,所以用+,如果是找存在路径就用或。
count=1+ movingCountCore(threshold,rows,cols,row-1,col,visited)+//上
movingCountCore(threshold,rows,cols,row+1,col,visited)+//下
movingCountCore(threshold,rows,cols,row,col-1,visited)+//左
movingCountCore(threshold,rows,cols,row,col+1,visited);//右
}
//2.3 返回计数
return count;
}
//3.匹配函数bool,参数::阈值int,矩阵行数int,矩阵列数int,当前行数int,当前列数int,访问矩阵数组bool*,返回值:是否满足条件 bool
bool check(int threshold,int rows,int cols,int row,int col,bool* visited)
{
//3.1 如果该位置满足条件:1.不越界。2.不超过阈值。3.未曾访问过。则返回真。
if(row<rows&&col<cols&&col>=0&&row>=0&&!visited[col+cols*row]&&getDigitSum(row)+getDigitSum(col)<=threshold)
return true;
//3.2 否则返回假。
return false;
}
//4. 计算数位之和函数int,参数:数字int,返回值:数位之和int。
int getDigitSum(int num)
{
//4.1 初始化数为之和为0
int sum=0;
//4.2 循环
while(num>0)
{
//4.2.1 取余,先加个位数
sum+=num%10;
//4.2.2 除以10,降一位
num/=10;
}
//4.3 返回sum
return sum;
}
};