- Cut Off Trees for Golf Event
You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-negative 2D map, in this map:
0 represents the obstacle can’t be reached.
1 represents the ground can be walked through.
The place with number bigger than 1 represents a tree can be walked through, and this positive number represents the tree’s height.
You are asked to cut off all the trees in this forest in the order of tree’s height - always cut off the tree with lowest height first. And after cutting, the original place has the tree will become a grass (value 1).
You will start from the point (0, 0) and you should output the minimum steps you need to walk to cut off all the trees. If you can’t cut off all the trees, output -1 in that situation.
You are guaranteed that no two trees have the same height and there is at least one tree needs to be cut off.
Example
Input:
[
[1,2,3],
[0,0,4],
[7,6,5]
]
Output: 6
Input:
[
[1,2,3],
[0,0,0],
[7,6,5]
]
Output: -1
Input:
[
[2,3,4],
[0,0,5],
[8,7,6]
]
Output: 6
Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly without walking.
Notice
size of the given matrix will not exceed 50x50.
这题类似骑士遍历题,也是基于BFS,但稍复杂一些。
思路:
- 将trees按低到高排序。
- 按trees从低到高,每次用BFS找到从ith高的树到i+1th高的树的最短路径。返回所有最短路径之和即可。
- 因为每次都要重新调用BFS,所以每次visited map都要初始化。
- 砍完某树后应该将其高度设为1。
代码如下:
struct Node {
int row;
int col;
int height;
Node(int x, int y, int z) : row(x), col(y), height(z) {}
bool operator < (const Node & node) const {
return height < node.height;
}
};
class Solution {
public:
/**
* @param forest: a list of integers
* @return: return a integer
*/
int cutOffTree(vector<vector<int>> &forest) {
if (forest.size() == 0) return 0;
int lenR = forest.size();
int lenC = forest[0].size();
vector<Node> trees;
for (int i = 0; i < lenR; ++i) {
for (int j = 0; j < lenC; ++j) {
int val = forest[i][j];
if ((val != 0) && (val != 1))
trees.push_back(Node(i, j, val));
}
}
sort(trees.begin(), trees.end());
int len = trees.size() - 1; // one less than the trees size
int result = 0;
Node node0 = Node(0, 0, forest[0][0]);
result += bfs(forest, node0, trees[0]);
for (int i = 0; i < len; ++i) {
int steps = bfs(forest, trees[i], trees[i + 1]);
if (steps == -1)
return -1;
else
result += steps;
}
return result;
}
private:
int bfs(vector<vector<int>> &forest, Node &src, Node &dest) {
//down, left, up, right
vector<int> dirR = {1, 0, -1, 0}; //col
vector<int> dirC = {0, -1, 0, 1}; //row
//each time of bfs, the visited map needs reset
vector<vector<int>> visited(forest.size(), vector<int>(forest[0].size(), 0));
queue<Node> q;
q.push(src);
int steps = 0;
while(!q.empty()) {
int qSize = q.size();
for (int i = 0; i < qSize; ++i) {
Node n = q.front();
q.pop();
if ((n.row == dest.row) && (n.col == dest.col)) {
forest[dest.row][dest.col] = 1; //after the tree is cut, set the height as 1.
return steps;
}
for (int j = 0; j < 4; ++j) {
int r = n.row + dirR[j];
int c = n.col + dirC[j];
if ((r >= 0 && r < forest.size()) &&
(c >= 0 && c < forest[0].size()) &&
(forest[r][c] > 0) && (visited[r][c] == 0)) {
Node neighbor = Node(r, c, forest[r][c]);
q.push(neighbor);
//should not set the neighbor.height = 1 here as it will be accessed in the following bfs calls
visited[r][c] = 1;
}
}
}
steps++;
}
return -1;
}
};
本文探讨了一种基于BFS算法的森林砍树路径规划问题,旨在为高尔夫赛事清理场地。通过将树木按高度排序并寻找从一棵树到下一棵树的最短路径,实现了从起点到所有树的最小步数计算。
168万+

被折叠的 条评论
为什么被折叠?



