Featured image of post 剑指 Offer 13. 机器人的运动范围

剑指 Offer 13. 机器人的运动范围

题目描述

地上有一个 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

解法一:BFS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
func movingCount(m int, n int, k int) int {
    getSum := func(num int) int {
        res := 0
        for num > 0 {
            res += num % 10
            num /= 10
        }
        return res
    }
    visited := make([][]bool, m)
    for i := 0; i < m; i++ {
        visited[i] = make([]bool, n)
    }
    dirs := [][2]int{{1, 0}, {0, 1}}
    var queue [][2]int
    queue = append(queue, [2]int{0, 0})
    visited[0][0] = true
    ans := 0
    for len(queue) > 0 {
        ans++
        cur := queue[0]
        queue = queue[1:]
        for _, dir := range dirs {
            ni, nj := cur[0]+dir[0], cur[1]+dir[1]
            if ni < 0 || ni >= m || nj < 0 || nj >= n || visited[ni][nj] || getSum(ni)+getSum(nj) > k {
                continue
            }
            visited[ni][nj] = true
            queue = append(queue, [2]int{ni, nj})
        }
    }
    return ans
}

解法二:动态规划

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
func movingCount(m int, n int, k int) int {
    getSum := func(i int, j int) (ans int) {
        for i > 0 || j > 0 {
            ans += i%10 + j%10
            i /= 10
            j /= 10
        }
        return
    }

    // dp[i][j] 表示机器是能否到达坐标为 (i, j) 的格子
    dp := make([][]bool, m)
    for i := 0; i < m; i++ {
        dp[i] = make([]bool, n)
    }

    ans := 1
    dp[0][0] = true
    for i := 1; i < m; i++ {
        if getSum(i, 0) <= k && dp[i-1][0] {
            dp[i][0] = true
            ans++
        }
    }
    for j := 1; j < n; j++ {
        if getSum(0, j) <= k && dp[0][j-1] {
            dp[0][j] = true
            ans++
        }
    }
    for i := 1; i < m; i++ {
        for j := 1; j < n; j++ {
            if getSum(i, j) <= k {
                dp[i][j] = dp[i-1][j] || dp[i][j-1]
            }
            if dp[i][j] {
                ans++
            }
        }
    }
    return ans
}
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计