剑指Offer-机器人的运动范围

95 阅读1分钟

题目

地上有一个 mm 行和 nn 列的方格,横纵坐标范围分别是 0∼m−10∼m−1 和 0∼n−10∼n−1。 一个机器人从坐标 (0,0)(0,0) 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格。 但是不能进入行坐标和列坐标的数位之和大于 kk 的格子。 请问该机器人能够达到多少个格子? 注意: 0<=m<=50 0<=n<=50 0<=k<=100 样例1 输入:k=7, m=4, n=5 输出:20 样例2 输入:k=18, m=40, n=40 输出:1484 解释:当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。 但是,它不能进入方格(35,38),因为3+5+3+8 = 19。

解析

BFS即可,不继续下去的条件就是,横纵坐标超出范围,或数位之和大于k

代码

C++

class Solution {
public:
    int get_sum(pair<int, int> p) {
        int s = 0;
        while (p.first) {
            s += p.first % 10;
            p.first /= 10;
        }
        while (p.second) {
            s += p.second % 10;
            p.second /= 10;
        }
        return s;
    }
    
    int movingCount(int threshold, int rows, int cols)
    { 
        if (!rows || !cols) return 0;
        queue<pair<int, int>> q;
        vector<vector<bool>> st(rows, vector<bool>(cols, false));
        
        int ans = 0;
        q.push({0, 0});
    
        int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
        
        while (!q.empty())
        {
            auto t = q.front();
            q.pop();
            if (st[t.first][t.second] || get_sum(t) > threshold) continue;
            ans ++ ;
            st[t.first][t.second] = true;
            for (int i = 0; i < 4; i ++ ) {
                int x = t.first + dx[i], y = t.second + dy[i];
                if (x >= 0 && x < rows && y >= 0 && y < cols) q.push({x, y});
            }
            
        }
        
        return ans;
    }
};

Python

class Solution(object):
    def get_sum(self, num):
        ans = 0
        while num:
            ans += num % 10
            num //= 10
        return ans
        
        
    def movingCount(self, threshold, rows, cols):
        """
        :type threshold: int
        :type rows: int
        :type cols: int
        :rtype: int
        """
        if not rows or not cols:
            return 0
        
        st = [[False for _ in range(cols)] for _ in range(rows)]
        
        dx, dy = [-1, 0, 1, 0], [0, 1, 0, -1]
        
        q = [(0, 0)]
        
        ans = 0
        
        while len(q) > 0:
            x, y = q.pop(0)
            if st[x][y] or self.get_sum(x) + self.get_sum(y) > threshold:
                continue
            ans += 1
            st[x][y] = True
            
            for i in range(4):
                a, b = x + dx[i], y + dy[i]
                if a < 0 or a >= rows or b < 0 or b >= cols:
                    continue
                q.append((a, b))
        return ans
                
        
        
        

GO

type Point struct {
    x int
    y int 
}
func movingCount(threshold, rows, cols int) int {
    q := make([]Point, 0)
    if rows <= 0 || cols <= 0 {
        return 0
    }
    
    st := make([][]bool, rows)
    for i := 0; i < rows; i ++ {
        st[i] = make([]bool, cols)
    }
    dx, dy := []int{-1, 0, 1, 0}, []int{0, 1, 0, -1}
    q = append(q, Point{0, 0})

    ans := 0
    
    for len(q) > 0 {
        t := q[0]
        q = q[1:]
        if st[t.x][t.y] || get_sum(t.x, t.y) > threshold {
            continue
        }
        ans ++ 
        st[t.x][t.y] = true
        for i := 0; i < 4; i ++ {
            a, b := t.x + dx[i], t.y + dy[i]
            if a < 0 || a >= rows || b < 0 || b >= cols {
                continue
            }
            q = append(q, Point{a, b});
        }
    }
    
    return ans;
}
func get_single(a int) int {
    ans := 0
    for a > 0 {
        ans += a % 10
        a /= 10
    }
    return ans
}
func get_sum(a, b int) int {
    return get_single(a) + get_single(b)
}