当前位置:  首页>> 技术小册>> 数据结构与算法(下)

题目描述

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

解法

从坐标(0, 0) 开始移动,当它准备进入坐标(i, j),判断是否能进入,如果能,再判断它能否进入 4 个相邻的格子 (i-1, j), (i+1, j), (i, j-1), (i, j+1)。

  1. /**
  2. * @author bingo
  3. * @since 2018/11/20
  4. */
  5. public class Solution {
  6. /**
  7. * 计算能到达的格子数
  8. * @param threshold 限定的数字
  9. * @param rows 行数
  10. * @param cols 列数
  11. * @return 格子数
  12. */
  13. public int movingCount(int threshold, int rows, int cols) {
  14. if (threshold < 0 || rows < 1 || cols < 1) {
  15. return 0;
  16. }
  17. boolean[] visited = new boolean[rows * cols];
  18. return getCount(threshold, 0, 0, rows, cols, visited);
  19. }
  20. private int getCount(int threshold, int i, int j, int rows, int cols, boolean[] visited) {
  21. if (check(threshold, i, j, rows, cols, visited)) {
  22. visited[i * cols + j] = true;
  23. return 1
  24. + getCount(threshold, i - 1, j, rows, cols, visited)
  25. + getCount(threshold, i + 1, j, rows, cols, visited)
  26. + getCount(threshold, i, j - 1, rows, cols, visited)
  27. + getCount(threshold, i, j + 1, rows, cols, visited);
  28. }
  29. return 0;
  30. }
  31. private boolean check(int threshold, int i, int j, int rows, int cols, boolean[] visited) {
  32. return i >= 0
  33. && i < rows
  34. && j >= 0
  35. && j < cols
  36. && !visited[i * cols + j]
  37. && getDigitSum(i) + getDigitSum(j) <= threshold;
  38. }
  39. private int getDigitSum(int i) {
  40. int res = 0;
  41. while (i > 0) {
  42. res += i % 10;
  43. i /= 10;
  44. }
  45. return res;
  46. }
  47. }

测试用例

  1. 功能测试(方格为多行多列;k 为正数);
  2. 边界值测试(方格只有一行或者一列;k = 0);
  3. 特殊输入测试(k < 0)。

该分类下的相关小册推荐: