机器人的运动范围

未匹配的标注

题目描述

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

示例

输入:

5,10,10

输出:

21

数位之和

例如,123 的数位之和等于 1+2+3=6。计算某个数的数位之和代码如下所示:

/**
* 计算数位之和
*
* @param int $num 整型数
* @return int
*/
public function sum($num)
{
    $result = 0;
    while ($num) {
        $result += $num % 10;
        $num    = floor($num / 10);
    }
    return $result;
}

分析

蓝色格子表示机器人可到达。
由下面6张图可知,随着 k 值的变大,新加入的蓝色方格都可以由上方或左方的格子移动一步得到。最后其他不连通的蓝色方格区域会随着 k 的增大而连通,且连通的时候也是由上方或左方的格子移动一步得到,因此我们可以将我们的搜索方向缩减为向右或向下。

PP1ccJXBO9.png!large uynbZPYGRw.png!large 5tRPryR0vM.png!large HEHwkfKQLm.png!large SlXxcBaBZH.png!large VLKNWW2WOS.png!large

代码

<?php

namespace app\controller;

class Index
{
    /**
     * 机器人的运动范围
     *
     * @param int $threshold 阈值k
     * @param int $rows      行
     * @param int $cols      列
     * @return mixed
     */
    public function movingCount($threshold, $rows, $cols)
    {
        $col     = array_fill(0, $cols, 0);    // 初始化 $cols 个元素的一维数组
        $visited = array_fill(0, $rows, $col); // 初始化 $rows × $cols 个元素的二维数组

        return $this->DFS(0, 0, $rows, $cols, $visited, $threshold);
    }

    /**
     * 深度遍历
     *
     * @param int   $i         当前行
     * @param int   $j         当前列
     * @param int   $rows      总行数
     * @param int   $cols      总列数
     * @param array $visited   二维数组
     * @param int   $threshold 阈值k
     * @return int
     */
    public function DFS($i, $j, $rows, $cols, &$visited, $threshold)
    {
        // 如果: 超过行数 || 超过列数 || 数位之和大于阈值 || 格子已遍历过
        if ($i>=$rows || $j>=$cols || $this->sum($i)+$this->sum($j) > $threshold || $visited[$i][$j])
            return 0;

        // 1 标记格子已遍历过
        $visited[$i][$j] = 1;

        return $this->DFS($i + 1, $j, $rows, $cols, $visited, $threshold)// $i+1:往当前格子的下边走一步
            + $this->DFS($i, $j + 1, $rows, $cols, $visited, $threshold) // $j+1:往当前格子的右边走一步
            + 1;
    }

    /**
     * 计算数位之和
     *
     * @param int $num 整型数
     * @return int
     */
    public function sum($num)
    {
        $result = 0;
        while ($num) {
            $result += $num % 10;
            $num    = floor($num / 10);
        }
        return $result;
    }
}

笔记

array_fill(int $start_key, int $num, mixed $value):用给定的值填充数组

$start_key:键开始的值
$num:填充 $num 个
$value:填充的值

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~