• 剑指 Offer 13. 机器人的运动范围


    方法一:深度优先遍历 DFS
    深度优先搜索: 可以理解为暴力法模拟机器人在矩阵中的所有路径。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。

    剪枝: 在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,称之为 可行性剪枝 。

    int is_illegal(int row, int col, int k)
    {
        int sum = 0;
        while (row > 0)
        {
            sum += row % 10;
            row /= 10;
        }
        while (col > 0)
        {
            sum += col % 10;
            col /= 10;
        }
        return sum <= k;
    }
    
    void dfs(int m, int n, int k, int row, int col, int& sum, vector<vector<int>>& bitMap)
    {
        //深度优先
        if (row < 0 || row >= m || col < 0 || col >= n || !is_illegal(row, col, k) || bitMap[row][col] == 1)
            return;
    
        bitMap[row][col] = 1;
        sum++;
        dfs(m, n, k, row, col + 1, sum, bitMap);        //先一直向右搜索
        dfs(m, n, k, row + 1, col, sum, bitMap);        //回到上一个节点一直向下搜索
    }
    
    int movingCount(int m, int n, int k) {
        vector<vector<int>> bitMap(m, vector<int>(n, 0));
    
        int sum = 0;
        dfs(m, n, k, 0, 0, sum, bitMap);
    
        return sum;
    }

    方法二:广度优先遍历 BFS
    BFS/DFS : 两者目标都是遍历整个矩阵,不同点在于搜索顺序不同。DFS 是朝一个方向走到底,再回退,以此类推;BFS 则是按照“平推”的方式向前搜索。
    BFS 实现: 通常利用队列实现广度优先遍历。

    void bfs(int m, int n, int k)
    {
        int sum = 0;
        vector<vector<int>> bitMap(m, vector<int>(n, 0));
        std::queue<std::pair<int, int>> que;
        que.push(std::make_pair(0, 0));
        while (!que.empty())
        {
            
            auto& node = que.front();
            if (!is_illegal(node.first, node.second, k) || bitMap[node.first][node.second] == 1)
            {
                //会有重复添加的值,这里要剪枝
                que.pop();
                continue;
            }
            sum++;
            bitMap[node.first][node.second] = 1;
            if (node.first < m && node.second + 1 < n && bitMap[node.first][node.second + 1] == 0 && is_illegal(node.first, node.second + 1, k))
                que.push(std::make_pair(node.first, node.second + 1));
            if (node.first + 1 < m && node.second < n && bitMap[node.first + 1][node.second] == 0 && is_illegal(node.first + 1, node.second, k))
                que.push(std::make_pair(node.first + 1, node.second));
            que.pop();
        }
    }

  • 相关阅读:
    bzoj1600 [Usaco2008 Oct]建造栅栏(递推)
    bzoj1607 / P2926 [USACO08DEC]拍头Patting Heads
    bzoj2733 / P3224 [HNOI2012]永无乡(并查集+线段树合并)
    loj2163 / bzoj2212 / P3521 [POI2011]ROT-Tree Rotations(线段树合并)
    UVA11090 Going in Cycle!!(二分判负环)
    【C++】位应用(2)-设置某位的值
    【C++】位应用(2)-设置某位的值
    【C++】位操作的应用
    【C++】位操作的应用
    C++ 强转注意问题
  • 原文地址:https://www.cnblogs.com/jiguang321/p/14117292.html
Copyright © 2020-2023  润新知