BFS(六)JZ13 机器人的运动范围

文章描述了一个机器人在rows行cols列的网格中移动的问题,其不能进入行坐标和列坐标的数位之和大于threshold的格子。使用广度优先搜索(BFS)策略来计算机器人能到达的格子数量,当threshold、rows和cols给定时,返回可达格子的数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 机器人的运动范围_牛客题霸_牛客网

描述

地上有一个 rows 行和 cols 列的方格。坐标从 [0,0] 到 [rows-1,cols-1] 。一个机器人从坐标 [0,0] 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 threshold 的格子。 例如,当 threshold 为 18 时,机器人能够进入方格   [35,37] ,因为 3+5+3+7 = 18。但是,它不能进入方格 [35,38] ,因为 3+5+3+8 = 19 。请问该机器人能够达到多少个格子?

数据范围: 0≤threshold≤15 0≤threshold≤15  ,1≤rows,cols≤100 1≤rows,cols≤100 

进阶:空间复杂度 O(nm) O(nm)  ,时间复杂度 O(nm) O(nm) 

示例1

输入:

1,2,3
返回值:
3

示例2

输入:

0,1,3
返回值:
1

示例3

输入:

10,1,100
返回值:
29

说明:

[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[0,10],[0,11],[0,12],[0,13],[0,14],[0,15],[0,16],[0,17],[0,18],[0,19],[0,20],[0,21],[0,22],[0,23],[0,24],[0,25],[0,26],[0,27],[0,28] 这29种,后面的[0,29],[0,30]以及[0,31]等等是无法到达的      

 【解法一】

知识点:队列

队列是一种仅支持在表尾进行插入操作、在表头进行删除操作的线性表,插入端称为队尾,删除端称为队首,因整体类似排队的队伍而得名。它满足先进先出的性质,元素入队即将新元素加在队列的尾,元素出队即将队首元素取出,它后一个作为新的队首。

思路:

深度优先搜索是一条路走到底,我们还可以尝试广度优先搜索。只要遍历的时候从起点开始,依次访问与其相邻的四个方向(如果可以访问),然后再将与这四个方向相邻的节点都依次加入队列中排队等待访问。这样下来,每次访问都是一圈一圈推进,因此是广度优先搜索。

具体做法:

  • step 1:检查若是threshold小于等于0,只能访问起点这个格子。
  • step 2:从起点开始广度优先搜索,将其优先加入队列中等待访问,队列记录要访问的坐标。
  • step 3:每次取出队列首部元素访问,进行标记,然后计数。
  • step 4:然后遍历四个方向相邻的格子,检查其有没有超过边界,是否被访问过了。同时用连除法分别计算每个下标的位数和,检查位数和是否大于threshold,如果满足可以访问的条件,则将其加入队列中等待访问,同时标记访问过了。
int nextp[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
struct Node
{
    int x;
    int y;
    Node(int a, int b)
    {
        x = a;
        y = b;
    }
};
class Solution {
public:
    int count = 0;
    bool _isvaled(int x, int y, int threshold)
    {
        int add = 0;
        while(x)
        {
            add += (x%10);
            x /= 10;
        }
        while(y)
        {
            add += (y%10);
            y /= 10;
        }
        if(add > threshold)
            return false;
        else
            return true;
    }
    void BFS(vector<vector<bool>> &book, int threshold, int row, int col)
    {
        queue<Node> q;
        q.push(Node(0,0));
        book[0][0] = true;
        while(!q.empty())
        {
                Node cur = q.front();
                q.pop();
                int curX = cur.x;
                int curY = cur.y;
                //book[curX][curY] = true; // 错误位置
                count++;
                for(int i = 0; i < 4; i++)
                {
                    int newX = curX + nextp[i][0];
                    int newY = curY + nextp[i][1];
                    if(newX<0 || newX>=row
                    || newY<0 || newY>=col)
                        continue;
                    if(book[newX][newY]==false && _isvaled(newX, newY, threshold)==true)
                    {
                        q.push(Node(newX, newY));
                        book[newX][newY] = true;
                    }
                }
        }
    }
    int movingCount(int threshold, int rows, int cols) {
        if(threshold<=0)
            return 1;
        vector<vector<bool>> book(rows, vector<bool> (cols, false));
        BFS(book, threshold, rows, cols);
        return count;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值