难度:低 / 2🥖
题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
思路分析:
- movingCount():多余的函数,因为是原题目给的模板。作用是函数入口,调用move()函数是他唯一的作用。
- move():传入参数:threshold 题目中的限制k;rows方格数组的总行数;cols方格数组的总列数;row 此时访问的行号,初始为0表示行从0开始访问;col 此时访问的列号,初始为0表示列从0开始访问;mark 标记方格,用于标示某行某列的格子是否被访问过。
函数流程:先判断该 [row][col]方格是否满足被访问的条件;满足条件则让count加1,然后递归进行上下左右的访问,即move函数中的return语句。
- limit():在dfs函数中的判断条件中使用,判断是否行坐标和列坐标的数位之和是否大于k。
/**
* @Description:
*
* 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,
* 每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。
* 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
* 但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
*
*/
public class Android {
/**
* @Description:
* 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,
* 每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。
* 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
* 但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
*
* @param threshold 题目中的限制k
* @param rows 方格行数m
* @param cols 方格列数n
* @return
*/
static public int movingCount(int threshold, int rows, int cols)
{
//标记方格,用于标示某一格是否访问过
int[][] mark = new int[rows][cols];
int count = move(threshold,rows,cols,0,0,mark);
return count;
}
/**
*
* @param threshold 题目中的限制k
* @param rows
* @param cols
* @param row 此时访问的行号,初始为0表示行从0开始访问
* @param col 此时访问的列号,初始为0表示列从0开始访问
* @param mark
* @return
*/
static int move(int threshold, int rows, int cols, int row, int col, int[][] mark) {
// 行或列超出数组限制[row < 0 || col < 0 ||row >= rows || col >= cols]
// 或 当前格已经被访问[mark[row][col] == 1]
// 或 不满足题目中的限制k的要求[ !limit(threshold,row,col) ]
if (row < 0 || col < 0 || row >= rows || col >= cols || mark[row][col] == 1 || !limit(threshold,row,col) )
{
return 0;
}
//不进入上边的if,证明可以访问
//标识该位置已经访问
mark[row][col] = 1;
// 返回 1 是当前位置可以访问,结果加一
// dfs(threshold, rows,cols , row+1, col, mark) 递归 , 行+1,即当前位置向右移动
//dfs(threshold, rows,cols , row-1, col, mark) 行-1,即当前位置向左移动
// dfs(threshold, rows,cols , row, col+1, mark); 列+1,向下移动
// dfs(threshold, rows,cols , row+1, col-1, mark);列-1,向上移动,此题无必要,因为是从[0,0]开始往下右移动,无需向上
return 1 + move(threshold, rows,cols , row+1, col, mark)
// + move(threshold, rows,cols , row-1, col, mark)
+ move(threshold, rows,cols , row, col+1, mark);
// + dfs(threshold, rows,cols , row+1, col-1, mark);
}
/**
* 题目中的限制:不能进入行坐标和列坐标的数位之和大于k的格子。
* 当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
* @param threshold :k
* @param row :行坐标
* @param col :列坐标
* @return
*/
static boolean limit(int threshold, int row, int col){
//是否可以访问标识符
boolean limit = true;
//行row的数位之和
int count_row = 0;
//列col的数位之和
int count_col = 0;
//获取行row的数位之和,例35 就是 3+5 = 8
while (row > 0)
{
count_row += row % 10;
row /= 10;
}
//获取列col的数位之和,例38 就是 3+8 = 11
while (col > 0)
{
count_col += col % 10;
col /= 10;
}
//进行判断:行坐标和列坐标的数位之和是否大于k
if (count_col + count_row > threshold)
{
//大于则不能进入
limit = false;
}
return limit;
}
public static void main(String[] args) {
int i = movingCount(10, 7, 7);
System.out.println(i);
}
}