栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

机器人的运动范围(深度优先遍历与广度优先遍历)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

机器人的运动范围(深度优先遍历与广度优先遍历)

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

 

示例 1:

输入:m = 2, n = 3, k = 1

输出:3

 

示例 2:

输入:m = 3, n = 1, k = 0

输出:1

 

提示:

1 <= n,m <= 100

0 <= k <= 20

 

解题思路:深度优先遍历

可以从左上角(0,0)开始向下与向右进行深度优先遍历,如果k很小,则在整个二维数组中,机器人可以运动的范围将被分割成几个不连通的部分,但随着k增大,逐渐开始连通,也是从机器人的右边和下边首先开始连通的,所以只用递归下下边和右边就行了。用深度优先遍历从(0,0)开始往右边或下边搜索到底,再返回上一个元素往另一个方向搜索,以此类推。

 

算法流程:

public:

1.创建标记二维数组flag标记已经走过的位置,并初始化为0

2.返回深度优先遍历函数dfs的返回值

传入(第一个位置的行数0,列数0,flag数组,地图行数m,地图列数n,k)

 

private:

1.定义dfs函数,传入(当前位置的函数 i,当前位置的列数 j,flag,m,n,k)

               如果i>=m(越界)或j>=n(越界)或 i 的个位数+ i 十位数+ j 的个位数+ j的十位数 > k 或flag[i][j]==true(走过了)

                       返回0

               flag[i][j]=1(标记走过的位置为true)

               返回 1+递归向下搜索+递归向右搜索

 

代码:

class Solution {

public:

    int movingCount(int m, int n, int k) {

    vector> flag(m,vector (n,0));

    return dfs(0,0,flag,m,n,k);

    }

    

private:

    int dfs(int i,int j,

vector> &flag,int m,int n,int k) {

    if(i>=m||j>=n||i%10+i/10+j%10+j/10>k||

flag[i][j]) return 0;

   flag[i][j]=true;

   return 1+dfs(i+1,j,flag,m,n,k)+

          dfs(i,j+1,flag,m,n,k);

}

 

};

 

 

解题思路:广度优先遍历

也可以用广度优先遍历从(0,0)开始,把其右边的位置(0,1)与其下边的位置(1,0)入队q,然后(0,0)出队。再队头元素(0,1)出队,再把其右边与下边的位置入队,以此类推。直到队列为空,则说明搜索结束。为了避免重复走过,也需flag标记函数。队列q需要存储位置,所以需要创建数组类型的队列。最后还要一个计数变量count统计可以运动到的位置的数目。

 

算法流程:

1.创建标记二维数组flag并初始化为0

2.创建数组类型的队列q

3.创建计数遍历count并初始化为0

4.把第一个位置[0,0]入队

5.循环直到队列为空

               创建数组arr存储队头元素

               队头元素出队

               创建遍历 i 存储位置的行数

               创建遍历 j 存储位置的列数

               创建遍历 a 存储行数的个位数与十位数之和

               创建遍历 b 存储列数的个位数与十位数之和

               如果行数或列数越界或a+b > k 或flag已走过

                       跳过本次循环执行下一个循环

               count++

               标记该位置为true

               该位置的下边位置入队

               该位置的右边位置入队

6.返回count

 

代码:

class Solution {

public:

    int movingCount(int m, int n, int k) {

    vector> flag(m,vector (n,0));

    queue> q;

    int count=0; 

    q.push({0,0});

    while(!q.empty()) {

        vector arr=q.front();

        q.pop();

        int i=arr[0],j=arr[1];

        int a=i%10+i/10;

        int b=j%10+j/10;

        if(i>=m||j>=n||a+b>k||flag[i][j])

        continue;

        count++;

        flag[i][j]=true;

        q.push({i+1,j});

        q.push({i,j+1});

    }

    return count;

    }

};

        

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873369.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号