###### tags: `LeetCode` `BFS` `Queue` `Hard` # LeetCode #675 [Cut Off Trees for Golf Event](https://leetcode.com/problems/cut-off-trees-for-golf-event/) ### (Hard) 你被請來給一個要舉辦高爾夫比賽的樹林砍樹。樹林由一個 m x n 的矩陣表示, 在這個矩陣中: 0 表示障礙,無法觸碰 1 表示地面,可以行走 比 1 大的數 表示有樹的單元格,可以行走,數值表示樹的高度 每一步,你都可以向上、下、左、右四個方向之一移動一個單位,如果你站的地方有一棵樹,那麼你可以決定是否要砍倒它。 你需要按照樹的高度從低向高砍掉所有的樹,每砍過一顆樹,該單元格的值變為 1(即變為地面)。 你將從 (0, 0) 點開始工作,返回你砍完所有樹需要走的最小步數。如果你無法砍完所有的樹,返回 -1 。 可以保證的是,沒有兩棵樹的高度是相同的,並且你至少需要砍倒一棵樹。 ![](https://i.imgur.com/fjHXE6z.png) ![](https://i.imgur.com/u0zq7e5.png) --- 由於題目規定要按照樹的高度, 從矮的砍到高的, 因此先遍歷整個forest, 遇到樹時儲存{樹的高度, 列座標, 行座標}(使用tuple), 遍歷完後對樹的數組進行排序(會按照tuple的第一個數字排序, 也就是樹高)。 接下來, 從{0,0}開始(題目規定), 對每一個樹的位置進行BFS搜尋以找到最短路徑, 並將路徑長加至答案中, 而在下一輪中, 原先到達的樹的位置改為出發位置, 並再往後找下一個樹的位置(同樣使用BFS找最短路徑), 直到找到最後一個樹的位置, 並回傳加總後的答案(總路徑長)。 --- ``` class Solution { public: int m, n; int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; int cutOffTree(vector<vector<int>>& forest) { vector<tuple<int, int, int>> trees;// height, x, y m = forest.size(); n = forest[0].size(); for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(forest[i][j]>1){ trees.push_back({forest[i][j], i, j}); } } } sort(trees.begin(), trees.end()); int ans = 0; int start_x = 0; int start_y = 0; for(auto& t:trees){ int end_x = get<1>(t); int end_y = get<2>(t); int step = bfs(forest, start_x, start_y, end_x, end_y); if(step==INT_MAX)return -1; start_x = end_x; start_y = end_y; ans+=step; } return ans; } int bfs(vector<vector<int>>& forest, int start_x, int start_y, int end_x, int end_y){ queue<pair<int, int>> q; vector<vector<int>> visited(m,vector<int>(n, 0)); q.push({start_x, start_y}); int step = 0; while(!q.empty()){ for(int i=q.size();i>0;i--){ pair<int, int> loc = q.front();q.pop(); int x = loc.first; int y = loc.second; if(x == end_x && y ==end_y)return step; for(int j=0;j<4;j++){ int tmp_x = x + dir[j][0]; int tmp_y = y + dir[j][1]; if(tmp_x<0||tmp_y<0||tmp_x==m||tmp_y==n||forest[tmp_x][tmp_y]==0||visited[tmp_x][tmp_y]==1)continue; q.push({tmp_x, tmp_y}); visited[tmp_x][tmp_y] = 1; } } step++; } return INT_MAX; } }; ```