题目描述:
地上有一个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左,向右,向上,向下移动一格,但不能进入行坐标和列坐标的位数之和大于k的格子。例如:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18;但它不能进入方格(35,38),因为3 + 5+3+8 = 19.请问该机器人最多能到达多少个格子?
分析:
和面试题13类似,这个方格也可以看成一个m*n的矩阵。同样在这个矩阵中,除边界上的格子之外其他格子都有四个相邻的格子。机器人从坐标(0,0)开始移动。当它准备进入坐标为(i,j)的格子时,通过检查坐标的数位和来判断机器人是否能够进入。如果机器人能够进入坐标为(i,j)的格子,我们接着再判断它能否进入四个相邻的格子(i,j-1)、(i-1,j),(i,j+1)和(i+1,j)。
package jianZhiOffer;
/*
* 面试题13:机器人的运动范围
* 题目:地上有一个m行n列的放个。一个机器人从坐标(0,0)的格子开始移动,它每次可以向左,右,上,下
* 移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能进入方格
* (35,37),因为3+5+3+7=18.但它不能进入方格(35,38),因为3+5+3+8=19.
* 请问该机器人能够到达多少个格子?
*/
public class Demo13 {
public static int movingCount(int threshold,int rows,int cols) {
if(threshold<0 || rows<=0 || cols<=0) //边界条件
return 0;
boolean[] visited = new boolean[rows*cols];//定义一个数组用来存储是否重复进入同一格
for(int i=0;i<rows*cols;i++)
visited[i] = false;
int count = movingCountCore(threshold,rows,cols,0,0,visited);
return count;
}
static int movingCountCore(int threshold,int rows,int cols,
int row,int col,boolean[] visited) {
int count=0;
if(check(threshold,rows,cols,row,col,visited)) {
visited[row*cols+col] = true;
count = 1+movingCountCore(threshold,rows,cols,row-1,col,visited)+
movingCountCore(threshold,rows,cols,row,col-1,visited)+
movingCountCore(threshold,rows,cols,row+1,col,visited)+
movingCountCore(threshold,rows,cols,row,col+1,visited);
}
return count;
}
static boolean check(int threshold,int rows,int cols,
int row,int col,boolean[] visited) {
if(row>=0 && row<=rows && col>=0 && col<cols
&&getDigitSum(row)+getDigitSum(col)<=threshold
&& !visited[row*cols+col])
return true;
return false;
}
static int getDigitSum(int number) {
int sum=0;
while(number>0) {
sum += number%10;
number /=10;
}
return sum;
}
public static void main(String[] args) {
Demo13 robot = new Demo13();
int count = robot.movingCount(4, 6, 6);
System.out.println(count);
}
}