Treasures in a map (2)
Write a program that, given a map with treasures and obstacles, computes the distance from a given initial position to the nearest accessible treasure. The allowed movements are horizontal or vertical, but not diagonal.
Input: Input begins with the number of rows n> 0 and the number of columns m>0 of the map. Follow n rows with m characters each. A dot .
indicates an empty position, an X
indicates an obstacle, and a t
indicates a treasure. Finally, two numbers r and c indicate the initial row and column (both of them starting at 1) where we must start looking for treasures. You can assume that r is between 1 and n, that c is between 1 and m, and that the initial position is always empty.
Output: Print the minimum number of steps to reach a treasure strating from the initial position. If no treasure is accessible, tell so.
For maze problems such as this, it is very convenient to assume that the graph lies in the rectangle defined by (1,1) and (n, m), and add rows 0 and n + 1 and columns 0 and m + 1 with obstacles.
using GridGraph = vector<vector<char>> ;
(int n, int m){
GridGraph read_grid_graph// n = number of rows
// m = number of columns
(n+2, vector<char>(m+2,'X'));// X denotes obstacles
GridGraph Gfor (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
>> G[i][j];
cin return G;
}
Therefore, for instance, a BFS in a maze will look like the following
//BFS in a maze
#include<vector>
#include<queue>
using namespace std;
const int NOTVISITED = -1;
<int> bfs(const GridGraph& G, int i0, int j0){
vector// G is a grid graph
// (i0,j0) is a vertex in G
// the algorithm returns a vector D. D[a][b] is the distance of (a,b) from source (i0,j0),
// or -1 if the vertex (a,b) is not reachable from (i0,j0)
int n = G.size();
int m = G[0].size();
<vector<int>> D(n, vector<int>(m, NOTVISITED));
vector<pair<int,int>> pq;
queue.push({i0,j0});
pq[i0][j0] = 0;
Dwhile(not pq.empty()){
auto current = pq.front();
.pop();
pqint i = current.first;
int j = current.second;
// here we might want to "visit" current
if (G[i-1][j] != 'X' and D[i-1][j] == NOTVISITED){
.push({i-1, j}); // up
pq[i-1][j] = D[i][j] + 1;
D}
if (G[i][j+1] != 'X' and D[i][j+1] == NOTVISITED){
.push({i, j+1}); // right
pq[i][j+1] = D[i][j] + 1;
D}
if (G[i+1][j] != 'X' and D[i+1][j] == NOTVISITED){
.push({i+1, j}); // down
pq[i+1][j] = D[i][j] + 1;
D}
if (G[i][j-1] != 'X' and D[i][j-1] == NOTVISITED){
.push({i, j-1}); // left
pq[i][j-1] = D[i][j] + 1;
D}
}
return D;
}
// Treasures in a map (2)
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
using GridGraph = vector<vector<char>> ;
(int n, int m){
GridGraph read_grid_graph// n = number of rows
// m = number of columns
(n+2, vector<char>(m+2,'X'));// X denotes obstacles
GridGraph Gfor (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
>> G[i][j];
cin return G;
}
const int NOTVISITED = -1;
int bfs(const GridGraph& G, int i0, int j0){
// G is a grid graph
// (i0,j0) is a vertex in G
// the algorithm returns a vector D. D[a][b] is the distance of (a,b) from source (i0,j0),
// or -1 if the vertex (a,b) is not reachable from (i0,j0)
int n = G.size();
int m = G[0].size();
<vector<int>> D(n, vector<int>(m, NOTVISITED));
vector<pair<int,int>> pq;
queue.push({i0,j0});
pq[i0][j0] = 0;
Dwhile(not pq.empty()){
auto current = pq.front();
.pop();
pqint i = current.first;
int j = current.second;
// here we might want to "visit" current
if (G[i][j] == 't') return D[i][j];
if (G[i-1][j] != 'X' and D[i-1][j] == NOTVISITED){
.push({i-1, j}); // up
pq[i-1][j] = D[i][j] + 1;
D}
if (G[i][j+1] != 'X' and D[i][j+1] == NOTVISITED){
.push({i, j+1}); // right
pq[i][j+1] = D[i][j] + 1;
D}
if (G[i+1][j] != 'X' and D[i+1][j] == NOTVISITED){
.push({i+1, j}); // down
pq[i+1][j] = D[i][j] + 1;
D}
if (G[i][j-1] != 'X' and D[i][j-1] == NOTVISITED){
.push({i, j-1}); // left
pq[i][j-1] = D[i][j] + 1;
D}
}
return NOTVISITED;
}
int main(){
int n, m;
>> n >> m;
cin auto G = read_grid_graph(n,m);
int r,c;
>> r >> c;
cin int dist = bfs(G, r, c);
if (dist == NOTVISITED) cout << "no treasure can be reached" << endl;
else cout << "minimum distance: " << dist << endl;
}