题目:地上有个m行n列的方格。一个机器人从坐标(0,0)的格子开始移动,它每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和大于k的格子。
例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7=18.但它不能进入方格(35,38),因为3+5+3+8=19.请问该机器人能够达到多少格子?
/**
* Created by apple on 17/6/4.
*
* @author WangSai
* 题目要求:
* 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四
* 个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人
* 能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8
* = 19。请问该机器人能够达到多少个格子?
*/
public class movingCount {
public static void main(String[] args) {
System.out.println(getMovingCount(4, 6, 6));
}
/**
* 可以到达的格子的数量
*
* @param threshold,门限值
* @param m,行数
* @param n,列数
* @return 可以到的的格子的数量
*/
public static int getMovingCount(int threshold, int m, int n) {
//异常值检测
if (threshold < 0 || m <= 0 || n <= 0)
return -1;
//是否访问过数组中特定位置的标志
boolean[] visted = new boolean[m * n];
return getMovingCountCore(threshold, m, n, 0, 0, visted);
}
/**
* @param threshold,门限值
* @param rows,矩阵的行数
* @param colms,矩阵的列数
* @param row,当前的行号
* @param colm,当前位置的列号
* @param visted,用一维数组记录,是否访问过该位置的标志
* @return 可以访问到的位置
*/
private static int getMovingCountCore(int threshold, int rows, int colms, int row,
int colm, boolean[] visted) {
if (row < 0 || row >= rows || colm < 0 || colm >= colms || checkSum(row, colm) > threshold ||
visted[row * colms + colm]) {
return 0;
}
//二维数组转成一维数组之后,标志是否访问过
visted[row * colms + colm] = true;
return 1 + getMovingCountCore(threshold, rows, colms, row - 1, colm, visted)
+ getMovingCountCore(threshold, rows, colms, row + 1, colm, visted)
+ getMovingCountCore(threshold, rows, colms, row, colm - 1, visted)
+ getMovingCountCore(threshold, rows, colms, row, colm + 1, visted);
}
//计算行坐标和列坐标的数位之和
private static int checkSum(int row, int colm) {
int sum = 0;
while (row > 0) {
sum += row % 10;
row /= 10;
}
while (colm > 0) {
sum += colm % 10;
colm /= 10;
}
return sum;
}
}