剑指offer-面试题67-机器人的运动范围

题目:地上有个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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值