JZ13 机器人的运动范围

这篇博客讨论了如何解决一个机器人在给定的二维网格中移动的问题,其中机器人的移动受到行和列坐标的数位之和不超过特定阈值的限制。作者分别展示了两种解决方案:一种是采用递归的深度优先搜索(DFS),另一种是使用宽度优先搜索(BFS)。这两种方法都在O(nm)的时间和空间复杂度内完成,并给出了具体的代码实现。博客还提到了使用`using`关键字为类型创建别名的用法。
摘要由CSDN通过智能技术生成

题目来源:机器人的运动范围_牛客题霸_牛客网

描述

地上有一个 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 ,1≤rows,cols≤100

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

示例1

输入:1,2,3

复制返回值:3

我的代码:

采用递归的方法,深度优先遍历

class Solution {
public:
    int a[4][2] = {-1,0,1,0,0,1,0,-1};
    int addSum(int a, int b){
        int re=0;
        for(int i=a; i>0;i/=10){
            re+=i%10;
        }
        for(int i=b; i>0;i/=10){
            re+=i%10;
        }
        //cout<<"ADD:"<<re<<endl;
        return re;
    }
    void FindStep(int threshold, int row, int col, int rows, int cols, int& re, vector<vector<int>>& v){
        //cout<<"Jing";
        if(row<0 || row>=rows || col<0 || col>=cols || v[row][col]==1 || addSum(row,col)>threshold){
            //cout<<row<<"    "<<col<<endl;
            return;
        }
        cout<<row<<"    "<<col<<endl;
        v[row][col]=1;
        re=re+1;
        cout<<re<<endl;
        for(int i=0;i<4;i++){
            FindStep( threshold, row+a[i][0], col+a[i][1], rows, cols, re,v);
        }
        //v[row][col]=0;
    }
    
    int movingCount(int threshold, int rows, int cols) {
        int re=0;//能到达的格子数
        if (threshold < 0) {
            return 0;
        }
        vector<vector<int>> v(rows,vector<int>(cols,0));
        FindStep( threshold, 0, 0, rows, cols,re,v);
        return re;
    }
};

采用BFS的答案:

借助队列采用深度优先遍历的方法:

class Solution {
public:
    int a[4][2] = {-1,0,1,0,0,1,0,-1};
    int addSum(int a, int b){
        int re=0;
        for(int i=a; i>0;i/=10){
            re+=i%10;
        }
        for(int i=b; i>0;i/=10){
            re+=i%10;
        }
        //cout<<"ADD:"<<re<<endl;
        return re;
    }
    
    int movingCount(int threshold, int rows, int cols) {
        if (threshold < 0) {
            return 0;
        }
        vector<vector<int>> v(rows,vector<int>(cols,0));//全部赋值为0
        int ret=0;
        using pi=pair<int,int>;//别名
        queue<pi> q;
        q.push({0,0});//将第一个数放入队列
        v[0][0]=1;
        
        while(!q.empty()){
            auto node=q.front();
            q.pop();
            ++ret;
            for(int i=0;i<4;i++){
                int r=node.first + a[i][0];
                int c=node.second + a[i][1];
                if(r>=0 && r<rows && c>=0 && c<cols && addSum(r,c)<=threshold && v[r][c]==0){
                    q.push({r,c});//如果符合条件,压入队列
                    v[r][c]=1;
                }
            }
        }
        return ret;
    }
};

在答案中出现了using,它可以用来为新的类型起别名。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值