剑指offer第二版-13机器人的运动范围

/**
 * 题目:机器人的运动范围
 * 地上有一个m行n列的方格,一个机器人从坐标(0,0)的各自开始移动,它每次可以向上下左右移动一格,但不能进入横纵坐标数位之和大于k的格子。
 * 例如,当k等于18时,机器人能进入(35,37),因为3+5+3+7=18;但却不能进入(35,38),因为3+5+3+8=19>18。
 * 请问该机器人能够到达多少个格子。
 * <p>
 * 思路:
 * 每前进一步后,可选移动项为上下左右四个;
 * 为了判断某一个格子是否可以进入从而进行计数,不仅需要考虑边界值,计算各位数字之和,更要判断该格子是否已经被访问过。
 * 所以需要一个布尔矩阵,用来记录各格子是否已被访问。
 * 整体思路与面试题12类似
 *
 * @author VicterTian
 * @version V1.0
 * @Date 2019/1/25
 */
public class P92_RobotMove {
	public static int movingCount(int threshold, int rowLen, int colLen) {
		if (threshold < 0 || rowLen < 0 || colLen < 0) {
			return 0;
		}
		boolean[][] visitFlag = new boolean[rowLen][colLen];
		for (int row = 0; row < rowLen; row++) {
			for (int col = 0; col < colLen; col++) {
				visitFlag[row][col] = false;
			}
		}

		return movingCountCore(threshold, rowLen, colLen, 0, 0, visitFlag);
	}

	private static int movingCountCore(int threshold, int rowLen, int colLen, int row, int col, boolean[][] visitFlag) {
		int count = 0;
		if (canGetIn(threshold, rowLen, colLen, row, col, visitFlag)) {
			visitFlag[row][col] = true;
			count = 1 + movingCountCore(threshold, rowLen, colLen, row + 1, col, visitFlag) +
					movingCountCore(threshold, rowLen, colLen, row - 1, col, visitFlag) +
					movingCountCore(threshold, rowLen, colLen, row, col + 1, visitFlag) +
					movingCountCore(threshold, rowLen, colLen, row, col - 1, visitFlag);
		}
		return count;
	}

	private static boolean canGetIn(int threshold, int rowLen, int colLen, int row, int col, boolean[][] visitFlag) {
		return row >= 0 && col >= 0 && row < rowLen && col < colLen && !visitFlag[row][col] && getDigSum(row) + getDigSum(col) <= threshold;
	}

	private static int getDigSum(int num) {
		int sum = 0;
		while (num > 0) {
			sum += num % 10;
			num /= 10;
		}
		return sum;
	}

	public static void main(String[] args) {
		System.out.println(movingCount(0, 3, 4));
		System.out.println(movingCount(1, 3, 4));
		System.out.println(movingCount(9, 2, 20));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值