Title Description:
The robot moves from the upper left corner of a (m times n) grid to the lower right corner ((m,n)). Some of the lattices in the grid are empty space, represented by(0) and others are obstacles, represented by(1). The robot can walk one grid in four directions at a time, but it can't continuously cross (k) obstacles to find the shortest path length. Starting point and midpoint guarantee is open space.
Ideas:
BFS is still the shortest path, but because it can not pass through the (k) barrier continuously, it is different from ordinary BFS that we need to consider several obstacles when we reach a grid, and even if the lattice has been visited, if the number of obstacles for new access can be less than the number of obstacles for previous access, it can also be accessed (here is the difference from ordinary BFS). (2) The results of the study are as follows:1) The results of the study are as follows:1) The results of the study are as follows:1) The results of the study are as follows:1. I didn't think of the latter point at first. I found the problem when I tuned the test data on udebug. I also had to consider the initial condition of \(m=1,n=1).
Code:
#include <iostream> #include <queue> #include <utility> #include <algorithm> #include <memory.h> using namespace std; const int maxn = 20 + 2; int b[maxn][maxn]; int d[maxn][maxn]; int obs[maxn][maxn]; int m, n, k; const int dr[] = { 0, -1, 0, 1}; const int dc[] = { 1, 0, -1, 0}; pair<int, int> walk(pair<int, int> u, int i){ pair<int, int> v; v.first = u.first + dr[i]; v.second = u.second + dc[i]; return v; } void solve(){ queue<pair<int, int> > q; q.push(make_pair(1, 1)); memset(d, -1, sizeof(d)); memset(obs, 0, sizeof(obs)); d[1][1] = 0; while(!q.empty()){ pair<int, int> u = q.front(); q.pop(); for(int i = 0; i < 4; ++i){ pair<int, int> v = walk(u, i); if(v.first == m && v.second == n) { //Arrive at the destination d[v.first][v.second] = d[u.first][u.second] + 1; printf("%d\n", d[v.first][v.second]); return; } if(v.first > 0 && v.first <= m && v.second > 0 && v.second <= n && (d[v.first][v.second]<0||d[v.first][v.second]>0&&obs[u.first][u.second]+1<obs[v.first][v.second])){ //No Outbound && (not visited | | but the current path takes fewer obstacles to reach this point) d[v.first][v.second] = d[u.first][u.second] + 1;//The distance from the update starting point to the grid if(b[v.first][v.second] == 1){ //If grid is an obstacle obs[v.first][v.second] = obs[u.first][u.second] + 1;//Obtaining the Number of Obstacles Continuously Passing through the Current Grid if(obs[v.first][v.second] > k) { d[v.first][v.second] = -1; obs[v.first][v.second] = 0; continue;}//If the number of obstacles exceeds the limit, mark the grid as no access and re-initialize its state. } else obs[v.first][v.second] = 0; //Clear the number of continuous obstacles without gridding q.push(v); } } } if(d[m][n] < 0) printf("-1\n");//Ultimately no access to the end point, output - 1 else printf("%d\n", d[m][n]); //Here is the boundary condition for m=1, n=1. } int main(){ //freopen("uva1600_in.txt", "r", stdin); //freopen("uva1600_out.txt", "w", stdout); int T; scanf("%d", &T); while(T--){ scanf("%d%d%d", &m, &n, &k); for(int i = 1; i <= m; ++i){ for(int j = 1; j <= n; ++j) scanf("%d", &b[i][j]); } solve(); } }