算法:机器人的运动范围

难度:低 / 2🥖

题目描述

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


思路分析:

  • movingCount():多余的函数,因为是原题目给的模板。作用是函数入口,调用move()函数是他唯一的作用。
  • move():传入参数:threshold     题目中的限制k;rows方格数组的总行数;cols方格数组的总列数;row   此时访问的行号,初始为0表示行从0开始访问;col   此时访问的列号,初始为0表示列从0开始访问;mark 标记方格,用于标示某行某列的格子是否被访问过。

函数流程:先判断该 [row][col]方格是否满足被访问的条件;满足条件则让count加1,然后递归进行上下左右的访问,即move函数中的return语句。

  • limit():在dfs函数中的判断条件中使用,判断是否行坐标和列坐标的数位之和是否大于k。


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


public class Android {

    /**
     * @Description:
     *      地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,
     *      每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。
     *      例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
     *      但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
     *
     * @param threshold     题目中的限制k
     * @param rows          方格行数m
     * @param cols          方格列数n
     * @return
     */
    static  public int movingCount(int threshold, int rows, int cols)
    {
        //标记方格,用于标示某一格是否访问过
        int[][] mark = new int[rows][cols];

        int count = move(threshold,rows,cols,0,0,mark);
        return count;
    }

    /**
     *
     * @param threshold     题目中的限制k
     * @param rows
     * @param cols
     * @param row   此时访问的行号,初始为0表示行从0开始访问
     * @param col   此时访问的列号,初始为0表示列从0开始访问
     * @param mark
     * @return
     */
    static  int move(int threshold, int rows, int cols, int row, int col, int[][] mark) {
//        行或列超出数组限制[row < 0 || col < 0 ||row >= rows || col >= cols]
//        或    当前格已经被访问[mark[row][col] == 1]
//        或   不满足题目中的限制k的要求[ !limit(threshold,row,col) ]
        if (row < 0 || col < 0 || row >= rows || col >= cols || mark[row][col] == 1 || !limit(threshold,row,col) )
        {
            return 0;
        }
        //不进入上边的if,证明可以访问
        //标识该位置已经访问
        mark[row][col] = 1;

        // 返回 1 是当前位置可以访问,结果加一
        // dfs(threshold, rows,cols , row+1, col, mark) 递归 , 行+1,即当前位置向右移动
        //dfs(threshold, rows,cols , row-1, col, mark) 行-1,即当前位置向左移动
//        dfs(threshold, rows,cols , row, col+1, mark); 列+1,向下移动
//        dfs(threshold, rows,cols , row+1, col-1, mark);列-1,向上移动,此题无必要,因为是从[0,0]开始往下右移动,无需向上
        return 1 + move(threshold, rows,cols , row+1, col, mark)
 //               +  move(threshold, rows,cols , row-1, col, mark)
                +  move(threshold, rows,cols , row, col+1, mark);
//                +  dfs(threshold, rows,cols , row+1, col-1, mark);



    }

    /**
     * 题目中的限制:不能进入行坐标和列坐标的数位之和大于k的格子。
     *              当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。
     * @param threshold     :k
     * @param row           :行坐标
     * @param col           :列坐标
     * @return
     */
    static   boolean limit(int threshold, int row, int col){
        //是否可以访问标识符
        boolean limit = true;
        //行row的数位之和
        int count_row = 0;
        //列col的数位之和
        int count_col = 0;

        //获取行row的数位之和,例35 就是 3+5 = 8
        while (row > 0)
        {
            count_row += row % 10;
            row /= 10;
        }

        //获取列col的数位之和,例38 就是 3+8 = 11
        while (col > 0)
        {
            count_col += col % 10;
            col /= 10;
        }


        //进行判断:行坐标和列坐标的数位之和是否大于k
        if (count_col + count_row > threshold)
        {
            //大于则不能进入
            limit = false;
        }
        return limit;
    }


    public static void main(String[] args) {
        int i = movingCount(10, 7, 7);
        System.out.println(i);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值