机器人的运动范围
来源于牛客网中的在线编程题目
题目描述
地上有一个 m m m行和 n n n列的方格。一个机器人从坐标 0 , 0 0,0 0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k k k的格子。 例如,当 k k k为18时,机器人能够进入方格 ( 35 , 37 ) (35,37) (35,37),因为 3 + 5 + 3 + 7 = 18 3+5+3+7 = 18 3+5+3+7=18。但是,它不能进入方格 ( 35 , 38 ) (35,38) (35,38),因为 3 + 5 + 3 + 8 = 19 3+5+3+8 = 19 3+5+3+8=19。请问该机器人能够达到多少个格子?
题目分析
将这个问题分解为小问题:考虑当前机器人所在格子是否可以进入。若不能进入,则进入格子总数不变;若可以进入,则格子总数为
1
+
1+
1+向四个方向分别移动可以进入的格子总和。
实现分析
1、若机器人当前所在格子坐标超出了设定的格子坐标范围,则自然不能进入,从当前格子不能继续移动,返回0;
2、若机器人当前所在格子已经进入过了,也就不能再算入格子总数,若进入当前格子则会重复移动路径,因此不进入,返回0;
3、若当前机器人所在格子坐标合法且未进入过,则判断是否满足设定的条件,若满足,则返回1+往四个方向移动将能进入到的格子总数即为可达到的格子总数;若不满足,则不进入,返回0。
代码实现
使用Java语言代码实现
包含三个方法:
checkSum(int i):计算
i
i
i变量表示的数字各个数字位的和
movingCountOne(int threshold, int i, int j, int rows, int cols, boolean[][] visited):计算机器人位于
(
i
,
j
)
(i,j)
(i,j)表示的格子时可到达的格子总数
movingCount(int threshold, int rows, int cols):计算机器人从
(
0
,
0
)
(0,0)
(0,0)出发可到达的格子总数,即位于
(
0
,
0
)
(0,0)
(0,0)时可以到达的格子总数
public class Solution {
public int checkSum(int i){
int sum = 0;
while(i!=0){
sum = sum + i % 10;
i = i / 10;
}
return sum;
}
public int movingCountOne(int threshold, int i, int j, int rows, int cols, boolean[][] visited){
//当前格子的坐标越界了或者格子已经来过了
if(i<0 || i>=rows || j<0 || j>=cols || visited[i][j]==true){
return 0;
}
int sum = checkSum(i) + checkSum(j);
if(sum > threshold){
return 0;
}else{
visited[i][j]=true;
return 1+movingCountOne(threshold, i+1,j, rows,cols,visited)
+movingCountOne(threshold, i,j+1, rows,cols,visited)
+movingCountOne(threshold, i-1,j, rows,cols,visited)
+movingCountOne(threshold, i,j-1, rows,cols,visited);
}
}
public int movingCount(int threshold, int rows, int cols)
{
boolean[][] visited = new boolean[rows][cols];//记录每个格子是否进入过了
for(int i = 0; i< rows; i++){
for(int j=0; j< cols;j++)
visited[i][j]=false;
}
return movingCountOne(threshold, 0, 0, rows, cols, visited);
}
}