仓库源文站点原文


title: '算法:机器人的运动范围' cover: https://img.paulzzh.com/touhou/random?68 categories: 算法题目 date: 1996-07-27 08:00:00 tags: [算法题目, DFS]

toc: true

<br/>

<!--more-->

机器人的运动范围

机器人的运动范围

地上有一个m行和n列的方格。

一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。

例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。

请问该机器人能够达到多少个格子?


分析

在四个方向进行DFS搜索, 访问过得增加标记;

当前节点满足要求的增加结果计数;

但是不回溯(防止产生重复结果)


代码

public class Solution {

    private static boolean[][] visited;

    public int movingCount(int threshold, int rows, int cols) {
        visited = new boolean[rows][cols];
        return helper(threshold, rows, cols, 0, 0);
    }

    private int helper(int threshold, int rows, int cols, int curRow, int curCol) {
        if (curRow < 0 || curRow >= rows
                || curCol < 0 || curCol >= cols
                || visited[curRow][curCol]
                || !checkVerify(threshold, curRow, curCol)) return 0;

        visited[curRow][curCol] = true;
        return 1 + helper(threshold, rows, cols, curRow + 1, curCol)
                + helper(threshold, rows, cols, curRow - 1, curCol)
                + helper(threshold, rows, cols, curRow, curCol + 1)
                + helper(threshold, rows, cols, curRow, curCol - 1);
    }

    private boolean checkVerify(int k, int curRow, int curCol) {
        int sum = 0;
        while (curRow != 0 || curCol != 0) {
            sum += curCol % 10 + curRow % 10;
            if (sum > k) return false;
            curRow /= 10;
            curCol /= 10;
        }
        return sum <= k;
    }
}