剑指 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。请问该机器人能够到达多少个格子?

解题思路

方法一:广度优先

首先需要一个函数得到某个位置的下标有多少位:

cpp 复制代码
int Solution::get(int x)
{
    int res = 0;
    for (; x; x /= 10)
        res += x % 10;
    return res;
}

通过上面的函数得到某个位置横坐标和纵坐标的位数,来和k比较是否满足题目要求。

广度优先采用队列的方式解决,用一个队列存储满足条件的位置,由于是从左上角(0,0)开始,因此只需要看它的右边和下边即可。将满足条件的点加入到队列中作为下一次需要被查询右边和下边的点。另外用一个二维数组标记已经被访问过的位置,因为向下和向右查找时包含被查询过的点。

当出现x<0或者y<0或者x>=m或者y<=n或者坐标位数和大于k时则跳过该点。

方法二:深度优先

深度优先则需要使用递归。首先需要搞清楚递归返回的条件。什么时候递归返回?当当前访问的横坐标或纵坐标>=m,n的值或者横坐标位数+纵坐标位数>k或者当前节点已经被访问过了(由于是向右和向下两个方向,因此不会出现i/j<0),此时返回0。(返回0而不是false是因为我们需要得到能到达的个数)

在深度优先中涉及到一个-8的操作,这里举例说明:

例如我们现在的i是19,下一次+1则为20,而19对应的位数和是10;但20对应的位数和是2。

代码

方法一:

cpp 复制代码
int Solution::get(int x)
{
    int res = 0;
    for (; x; x /= 10)
        res += x % 10;
    return res;
}

int Solution::movingCount(int m, int n, int k)
{
    if (!k) 
        return 1;

    std::queue<std::pair<int, int> > Q;
    int dx[2] = { 0, 1 };
    int dy[2] = { 1, 0 };
    std::vector<std::vector<int> > vis(m, std::vector<int>(n, 0));

    Q.push(std::make_pair(0, 0));
    vis[0][0] = 1;
    int ans = 1;

    while (!Q.empty()) {
        int x, y;
        std::tie(x, y) = Q.front();
        Q.pop();
        for (int i = 0; i < 2; ++i) {
            int tx = dx[i] + x;
            int ty = dy[i] + y;
            if (tx < 0 || tx >= m || ty < 0 || ty >= n || vis[tx][ty] || get(tx) + get(ty) > k) 
                continue;
            Q.push(std::make_pair(tx, ty));
            vis[tx][ty] = 1;
            ans++;
        }
    }
    return ans;
}

方法二:

cpp 复制代码
class Solution {
public:
    int movingCount(int m, int n, int k) {
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        return dfs(0, 0, k, visited);
    }

private:
    int dfs(int i, int j, int k, vector<vector<bool>>& visited) {
        if (i >= visited.size() || j >= visited[0].size() || visited[i][j] || getSum(i, j) > k) {
            return 0;
        }

        visited[i][j] = true;

        return 1 + dfs(i + 1, j, k, visited) + dfs(i, j + 1, k, visited);
    }

    int getSum(int i, int j) {
        int sum = 0;
        while (i > 0) {
            sum += i % 10;
            i /= 10;
        }
        while (j > 0) {
            sum += j % 10;
            j /= 10;
        }
        return sum;
    }
};
相关推荐
天空属于哈夫克31 天前
私域运营:如何用自动化做好客户跟进?
机器人·自动化·企业微信
懂压力传感器的涌客1 天前
机器人触觉传感器方案中FSR如何选型与集成
人工智能·机器人·压力传感器·fsr·源头工厂·fsr压力传感器
明志数科1 天前
机器人数据采集流程的工程实践:三条主流路线对比与选型分析
计算机视觉·自然语言处理·机器人
Hello Mr.Z1 天前
microduck_rl(MuJoCo+PPO+WandB+UV训练机器人)
机器人·uv·rl·ppo·microduck
rcms152702692181 天前
Yaskawa XU-RCM2500T-4机器人手臂模块
机器人
海盗12341 天前
AI 新闻日报 2026-09-07:GitHub 多模型编排、OpenClaw 2.0 多智能体、人形机器人破人类纪录
人工智能·机器人·github
天空属于哈夫克31 天前
企业微信开发:如何处理接口返回的异常数据?
机器人·自动化·企业微信
嘉立创FPC苗工1 天前
软硬共生:FPC与机器人的双向赋能,解锁智能装备进化新势能
人工智能·机器人·制造·fpc·电路板
初恋叫萱萱1 天前
企业微信智能化办公机器人部署与大语言模型集成实操深度指南
语言模型·机器人·企业微信
正在走向自律1 天前
爆火全网的2026机器人运动会:从赛场竞速到具身智能产业化的技术全解析
人工智能·机器人·具身智能·人形机器人·机器人运动会·百米竞速