剑指 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;
    }
};
相关推荐
HyperAI超神经6 小时前
未来具身智能的触觉革命!TactEdge传感器让机器人具备精细触觉感知,实现织物缺陷检测、灵巧操作控制
人工智能·深度学习·机器人·触觉传感器·中国地质大学·机器人智能感知·具身触觉
中关村科金18 小时前
中关村科金智能客服机器人如何解决客户个性化需求与标准化服务之间的矛盾?
人工智能·机器人·在线客服·智能客服机器人·中关村科金
lshzdq1 天前
【机器人】机械臂轨迹和转矩控制对比
人工智能·算法·机器人
夜幕龙2 天前
iDP3复现代码数据预处理全流程(二)——vis_dataset.py
人工智能·python·机器人
望获linux2 天前
赋能新一代工业机器人-望获实时linux在工业机器人领域应用案例
linux·运维·服务器·机器人·操作系统·嵌入式操作系统·工业控制
ai_lian_shuo2 天前
四、使用langchain搭建RAG:金融问答机器人--构建web应用,问答链,带记忆功能
python·ai·金融·langchain·机器人
我爱C编程2 天前
基于Qlearning强化学习的机器人路线规划matlab仿真
matlab·机器人·强化学习·路线规划·qlearning·机器人路线规划
野蛮的大西瓜2 天前
开源呼叫中心中,如何将ASR与IVR菜单结合,实现动态的IVR交互
人工智能·机器人·自动化·音视频·信息与通信
向阳逐梦4 天前
基于STM32F4单片机实现ROS机器人主板
stm32·单片机·机器人
朽木成才4 天前
小程序快速实现大模型聊天机器人
小程序·机器人