UVa1600
在长宽分别为m
和n
的矩形区域中,有些格子存在障碍物,机器人可以连续穿过k
个障碍物,求从矩形左上角到右下角的最短路径长度。
最短路径长度可以使用广搜求解。这道题不同的地方在于机器人可以连续穿过k
个障碍物,所以在广搜扩展时还应该记录机器人还能连续穿过多少个障碍物。
然后uDebug上有几个测试用例过不了,感觉应该是记录格子是否访问过的逻辑有错误。想了一下,正确的逻辑应该是记录机器人到达这个格子时还能连续穿过障碍物的数量,并使该值尽可能的大。
#include <iostream>
#include <array>
#include <deque>
#include <vector>
using namespace std;
struct Node
{
int i, j;
int k;
int step;
Node(int i, int j, int k, int step) : i(i), j(j), k(k), step(step) {}
};
class Solution
{
public:
Solution(const vector<vector<char>> &grid, int m, int n, int k) : length(-1)
{
vector<vector<int>> visited(grid.size(), vector<int>(grid[0].size(), -1));
const vector<array<int, 2>> directions = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
deque<Node> deq;
deq.emplace_back(0, 0, k, 0);
visited[0][0] = k;
while (!deq.empty()) {
Node curr = deq.front();
deq.pop_front();
if (curr.i == m - 1 && curr.j == n - 1) {
length = curr.step;
break;
}
for (const array<int, 2> &direction : directions)
{
Node next{ curr.i + direction[0], curr.j + direction[1], curr.k, curr.step + 1 };
if (0 <= next.i && next.i < m && 0 <= next.j && next.j < n) {
if (grid[next.i][next.j] == '0') {
next.k = k;
}
else {
next.k--;
if (next.k < 0) continue;
}
if (visited[next.i][next.j] == -1 || visited[next.i][next.j] < next.k) {
visited[next.i][next.j] = next.k;
deq.push_back(next);
}
}
}
}
}
int FindShortestPathLength()
{
return length;
}
private:
int length;
};
int main()
{
int cases = 0;
cin >> cases;
for (int c = 0; c < cases; c++)
{
int m, n, k;
cin >> m >> n >> k;
vector<vector<char>> grid(m, vector<char>(n, false));
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> grid[i][j];
}
}
Solution solution(grid, m, n, k);
cout << solution.FindShortestPathLength() << endl;
}
return 0;
}
/*
3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0
*/