地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1
输出:3
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
1 <= n,m <= 100
0 <= k <= 20
做了剑指offer12.矩阵中的路径之后再做这道题,一看就知道是一个搜索的题目,有这个思路之后开始写代码,写起来比offer12那道题还要简单一些,因为那道题还可能有重复的,每个都要找,还要保证res全局数组不能被替换掉了。这个题因为规定了只能从0,0开始,所以直接设置一个全局res累加就行了,因为m,n,k变量也是唯一的,都设置成全局变量了。标记是否找过的selected数组也是唯一的放在全局里面了
这个题直接用搜索的思想,从0,0开始,判断好越界、位和不能大于k值、是否找过这些条件,找一次res加一,并递归向上下左右找,最后在官方题解中看到,因为是从0,0开始的,并且位和都是往下往右递增的规律,所以可以优化成往下往右找就行了(优化了这个再提交,内存和时间都是有明显降低的)
贴出代码:
class Solution {
public $res = 0;
public $m;
public $n;
public $k;
public $selected = [];
/**
* @param Integer $m
* @param Integer $n
* @param Integer $k
* @return Integer
*/
function movingCount($m, $n, $k) {
$this->m = $m;
$this->n = $n;
$this->k = $k;
$this->dfs(0, 0);
return $this->res;
}
function dfs($i, $j)
{
$sum = $this->sum($i, $j);
if (($i < 0 || $i >= $this->m) || ($j < 0 || $j >= $this->n) || $sum > $this->k || isset($this->selected[$i][$j])) {
return null;
}
$this->selected[$i][$j] = 1;
$this->res++;
return ($this->dfs($i+1, $j)) ||
($this->dfs($i, $j+1));
}
function sum($i, $j)
{
$i = (string)$i;
$j = (string)$j;
$i_len = strlen($i);
$j_len = strlen($j);
$sum = 0;
while ($i_len--) {
$sum += $i[$i_len];
}
while ($j_len--) {
$sum += $j[$j_len];
}
return $sum;
}
}