AcWing 24. 机器人的运动范围(BFS和DFS)

AcWing 24. 机器人的运动范围

分析

这题是一道非常经典可以使用BFS也可以DFS的搜索题,题干有四连通。
①先做好一些初始工作:初始化队列、初始化记录状态的数组、初始化四连通数组
②接着就让队列一直循环
2.1 先从队列取值,再去掉队头
2.2 判断是否满足条件,若不满足就下一次循环
2.3 满足条件了,那就做题目中要求做的事。这题是要找能到达点有多少, 然后还要刷新状态
2.4 从中心点向四周扩散(四连通、八连通)

代码

bfs

class Solution {
public:
    int q[3000][2];
    int check(int a, int b) {
        int s = 0;
        while (a) {
            s += a % 10;
            a /= 10;
        }
        while (b) {
            s += b % 10;
            b /= 10;
        }
        return s;
    }
    int movingCount(int k, int rows, int cols)
    {
        //行数和列数都有可能为0
        if (!rows | !cols)
            return 0;
        //st数组用于判断每个位置是否被遍历过
        bool st[rows][cols];
        memset(st, 0, sizeof st);
        
        int hh = 0, tt = -1, ans = 0;
        int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
        
        //将初始状态入队
        q[++tt][0] = 0, q[tt][1] = 0;
        
        while (hh <= tt) {
            int a = q[hh][0], b = q[hh++][1];//取出队头元素
            //每取出一个元素,都需要判断是否被遍历过,或者行坐标和列坐标的数位之和是否大于 k
            if (st[a][b] || check(a, b) > k) continue;
            //如果当前坐标没有被遍历过且行坐标和列坐标的数位之和小于等于k,则这个坐标是可以进入的
            ans++;
            
            st[a][b] = 1;
            //向四连通方向遍历
            for (int i = 0; i < 4; i++) {
                int x = a + dx[i], y = b + dy[i];
                if (x >= 0 && x < rows && y >= 0 && y < cols) {
                    q[++tt][0] = x, q[tt][1] = y;
                }
            }
        }
        return ans;
    }
};

dfs

class Solution {
public:
    //st数组用于判断每个位置是否被遍历过
    bool st[51][51];
    //偏移量数组
    int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
    int ans;
    int check(int a, int b) {
        int s = 0;
        while (a) {
            s += a % 10;
            a /= 10;
        }
        while (b) {
            s += b % 10;
            b /= 10;
        }
        return s;
    }
    void dfs(int a, int b, int k, int rows, int cols) {
        //每遍历一个元素,都需要判断是否被遍历过,或者行坐标和列坐标的数位之和是否大于 k
        if (st[a][b] || check(a, b) > k) return;
        //如果当前坐标没有被遍历过且行坐标和列坐标的数位之和小于等于k,则这个坐标是可以进入的
        ans++;
        st[a][b] = 1;
        
        //向四连通方向遍历
        for (int i = 0; i < 4; i++) {
            int x = a + dx[i], y = b + dy[i];
            if (x >= 0 && x < rows && y >= 0 && y < cols) {
                   dfs(x, y, k, rows, cols);
            }
        }
    }
    
    int movingCount(int k, int rows, int cols)
    {
        //行数和列数都有可能为0
        if (!rows | !cols)
            return 0;
        
        dfs(0, 0, k, rows, cols);
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值