当前位置: 首页 > news >正文

BFS最短路径(十七)675. 为高尔夫比赛砍树 困难

675. 为高尔夫比赛砍树 

 

你被请来给一个要举办高尔夫比赛的树林砍树。树林由一个 m x n 的矩阵表示, 在这个矩阵中:

  • 0 表示障碍,无法触碰
  • 1 表示地面,可以行走
  • 比 1 大的数 表示有树的单元格,可以行走,数值表示树的高度

每一步,你都可以向上、下、左、右四个方向之一移动一个单位,如果你站的地方有一棵树,那么你可以决定是否要砍倒它。

你需要按照树的高度从低向高砍掉所有的树,每砍过一颗树,该单元格的值变为 1(即变为地面)。

你将从 (0, 0) 点开始工作,返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1

可以保证的是,没有两棵树的高度是相同的,并且你至少需要砍倒一棵树。

示例 1:

输入:forest = [[1,2,3],[0,0,4],[7,6,5]]
输出:6
解释:沿着上面的路径,你可以用 6 步,按从最矮到最高的顺序砍掉这些树。

示例 2:

输入:forest = [[1,2,3],[0,0,0],[7,6,5]]
输出:-1
解释:由于中间一行被障碍阻塞,无法访问最下面一行中的树。

示例 3:

输入:forest = [[2,3,4],[0,0,5],[8,7,6]]
输出:6
解释:可以按与示例 1 相同的路径来砍掉所有的树。
(0,0) 位置的树,可以直接砍去,不用算步数。

提示:

  • m == forest.length
  • n == forest[i].length
  • 1 <= m, n <= 50
  • 0 <= forest[i][j] <= 109

 下图中,从0,0 位置的 1 出发 ,走到下方的2 再走到4 5 8 10 12 14这样

那么此题就转化为了俩俩坐标之间的迷宫问题,只需要求出每俩坐标之间最小的步数,最后把所有的步数加起来即可。

 1、将给定的二维数组重新处理,使用一个Node结构体来进行存储,结构体内部有树高权值、以及树的横纵坐标。并且需要使用sort接口按照树高进行自定义排序。

 sort函数对结构体自定义排序

class Node {
public:
    int _key;
    pair<int, int> _PII;
    Node(int key, int i, int j) {
        _key = key;
        _PII.first = i;
        _PII.second = j;
    }
};
class Com {
public:
    bool operator()(const Node& left, const Node& right) {
        return left._key < right._key;
    }
};
sort(v.begin(), v.end(), Com());

 2、每次bfs访问俩个坐标之间的最小步数

i j 表示 当前位置,t_x  t_y 表示目标位置

进行bfs操作,将起始位置放入队列中,每轮将队列中所有一步能到达的位置加入队列,并进行判断处理。养成入队列进行操作的习惯。

    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int m, n;
    bool book[51][51] = {false};
    int bfs(int i, int j, int t_x, int t_y,
                   vector<vector<int>>& forest) {
        if(i == t_x && j == t_y)
            return 0;
        queue<pair<int, int>> q;
        memset(book, 0, sizeof book);
        int res = 0;
        q.push({i, j});
        book[i][j] = true;
        while (q.size()) {
            int size = q.size();
            res++;
            while (size--) 
            {
                auto [a, b] = q.front();
                q.pop();

                for (int k = 0; k < 4; k++) {
                    int x = a + dx[k];
                    int y = b + dy[k];
                    if (x >= 0 && y >= 0 && x < m && y < n &&
                        forest[x][y] != 0 && !book[x][y]) {
                        if(x == t_x && y == t_y)
                            return res;
                        book[x][y] = true;
                        q.push({x, y});
                    }
                }
            }
        }
        return -1;
    }

 3、调用bfs函数统计步数并求和

        3、对排序好的树俩俩之间求出最短步数 把每一段之间的最短步数相加求和即为结果
        int res = 0;
        int bx = 0, by = 0;
        for(auto &node : v)
        {
            int step = bfs(bx, by, node._PII.first, node._PII.second, forest);
            if(step == -1)
                return -1;
            res += step;
            bx = node._PII.first;
            by = node._PII.second;
        }
        return res;
class Node {
public:
    int _key;
    pair<int, int> _PII;
    Node(int key, int i, int j) {
        _key = key;
        _PII.first = i;
        _PII.second = j;
    }
};
class Com {
public:
    bool operator()(const Node& left, const Node& right) {
        return left._key < right._key;
    }
};
class Solution {
public:
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    int m, n;
    bool book[51][51] = {false};
    int bfs(int i, int j, int t_x, int t_y,
                   vector<vector<int>>& forest) {
        if(i == t_x && j == t_y)
            return 0;
        queue<pair<int, int>> q;
        memset(book, 0, sizeof book);
        int res = 0;
        q.push({i, j});
        book[i][j] = true;
        while (q.size()) {
            int size = q.size();
            res++;
            while (size--) 
            {
                auto [a, b] = q.front();
                q.pop();

                for (int k = 0; k < 4; k++) {
                    int x = a + dx[k];
                    int y = b + dy[k];
                    if (x >= 0 && y >= 0 && x < m && y < n &&
                        forest[x][y] != 0 && !book[x][y]) {
                        if(x == t_x && y == t_y)
                            return res;
                        book[x][y] = true;
                        q.push({x, y});
                    }
                }
            }
        }
        return -1;
    }
    int cutOffTree(vector<vector<int>>& forest) {
        vector<Node> v;
        m = forest.size(), n = forest[0].size();
        1、将每棵树树高和坐标位置放入vector中
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (forest[i][j] > 1) {
                    v.push_back(Node(forest[i][j], i, j));
                }
            }
        }
        2、按照树高大小进行排序
        sort(v.begin(), v.end(), Com());
        3、对排序好的树俩俩之间求出最短步数 把每一段之间的最短步数相加求和即为结果
        int res = 0;
        int bx = 0, by = 0;
        for(auto &node : v)
        {
            int step = bfs(bx, by, node._PII.first, node._PII.second, forest);
            if(step == -1)
                return -1;
            res += step;
            bx = node._PII.first;
            by = node._PII.second;
        }
        return res;
    }
};

相关文章:

  • 图像识别技术与应用(十六)
  • 科技工作者之家建设扬帆起航,为科技人才提供更多优质服务
  • lua C语言api学习1 编译第一个程序
  • 【巨人网络】25届春招、26届实习内推码,面经
  • nginx反向代理应用
  • SMC自修改
  • 二进制安装指定版本的MariaDBv10.11.6
  • 珠算之珠心算观想算盘
  • 基于Python+Vue开发的鲜花商城管理系统源码+运行步骤
  • 深度学习基础:线性代数本质4——矩阵乘法
  • 机器学习之超参数优化(Hyperparameter Optimization)
  • 【leetcode hot 100 23】合并K个有序链表
  • 图像识别技术与应用-YOLO
  • AI日报 - 2025年3月13日
  • Spring Boot 整合 Druid 并开启监控
  • 软件版本号设计
  • IEC61850标准下MMS 缓存报告控制块 ResvTms详细解析
  • 十种处理权重矩阵的方法及数学公式
  • python-leetcode 49.二叉树中的最大路径和
  • 【ES6】ES6中的类
  • 2025年上海科技节开幕,人形机器人首次登上科学红毯
  • 病愈出院、跳大神消灾也办酒,新华每日电讯:农村滥办酒席何时休
  • 商务部回应美方加严限制中国芯片:敦促美方立即纠正错误做法
  • 缅甸内观冥想的历史漂流:从心理治疗室到“非语言现场”
  • 经常口干口渴的人,要当心这些病
  • 京东回应外卖系统崩溃:订单暴涨所致,已恢复