[Problem description]
There is a maze described by a matrix. The matrix element values are 0 or 1 (0 indicates that the elements can enter, and 1 indicates that the elements cannot enter ). Now you need to find a shortest path from the top left to the bottom right (the matrix elements in the top left and bottom right are both 0 ).
For example, the following 4*4 matrix describes the Maze:
0, 0, 0, 0,
1, 0, 1, 0,
0, 0, 1, 0,
0, 1, 0, 0,
0, 0, 0, 0
The shortest path is 8 (the number of all locations in the path). The moving direction is right, bottom, and bottom.
[Problem Analysis]
Here, we can regard each element of the Matrix and Its moving direction as an undirected graph. If we can move from a position up, down, left, or right (the corresponding matrix element value is 0 ), it is equivalent to an edge in the graph. Therefore, you can search for the shortest path with the optimal graph width.
The C ++ implementation is as follows:
# Include <iostream>
# Include <queue>
# Include <vector>
# Include <cassert>
Using namespace STD;
// Find the optimal path from the upper left corner of the maze to the lower right corner (the Shortest Path)
// Search by Image Width first (hierarchical traversal)
Int searchmaze (int * a, int M, int N, vector <char> & Path)
{
// Maze location type
Typedef pair <int, int> position;
// Mobile operation type
Typedef unsigned char movetype;
Const movetype unvisited = 'n'; // not accessed
Const movetype start ='s '; // start point
Const movetype up = 'U'; // up
Const movetype right = 'R'; // right
Const movetype down = 'D'; // downward
Const movetype left = 'l'; // left
// Queue used for temporary storage
Queue <position> posqueue;
// Tag, used to distinguish layers of hierarchical traversal to calculate the path length
Position tag (-1,-1 );
// Target location
Position target (m-1, n-1 );
// Status array, used to record whether each location of the Maze has been accessed
Vector <movetype> state (M * n, unvisited );
// Mark whether the target location can be reached
Bool succeed = false;
// Press the start position into the queue and start searching
Posqueue. Push (make_pair (0, 0 ));
Posqueue. Push (TAG );
Int pathlength = 1;
State [0] = start;
// Search for the target location
While (! Posqueue. Empty ()){
Position cur = posqueue. Front ();
Posqueue. Pop ();
If (cur = target ){
// Locate the target location
Succeed = true;
Break;
}
If (cur = tag ){
// The traversal of this layer ends and enters the next layer
If (! Posqueue. Empty ()){
++ Pathlength;
Posqueue. Push (TAG );
}
Continue;
}
// Search up, down, left, and right from the current position
Int I = cur. first;
Int J = cur. Second;
Int index;
// Up
Index = (I-1) * n + J;
If (I> 0 & A [Index] = 0 & State [Index] = unvisited ){
Posqueue. Push (position (I-1, j ));
State [Index] = up;
}
// Right
Index = I * n + J + 1;
If (j <n-1 & A [Index] = 0 & State [Index] = unvisited ){
Posqueue. Push (position (I, j + 1 ));
State [Index] = right;
}
// Downward
Index = (I + 1) * n + J;
If (I <m-1 & A [Index] = 0 & State [Index] = unvisited ){
Posqueue. Push (position (I + 1, j ));
State [Index] = down;
}
// Left
Index = I * n + J-1;
If (j> 0 & A [Index] = 0 & State [Index] = unvisited ){
Posqueue. Push (position (I, j-1 ));
State [Index] = left;
}
}
If (succeed ){
// Can reach the target location and output the moving Operation Sequence
Path. Clear ();
Path. Reserve (pathlength );
Int I = m-1;
Int J = n-1;
Int Index = I * n + J;
For (; State [Index]! = Start; Index = I * n + J ){
Assert (State [Index]! = Unvisited & "cannot be an inaccessible location! ");
Path. push_back (State [Index]);
Switch (State [Index])
{
Case up:
++ I;
Break;
Case right:
-- J;
Break;
Case down:
-- I;
Break;
Case left:
++ J;
Break;
}
}
Reverse (path. Begin (), path. End ());
Return pathlength;
}
Return-1;
}
Int main ()
{
Const int M = 8;
Const int n = 8;
Int A [M * n] = {
0, 0, 0, 0, 1, 0, 0, 0,
1, 0, 1, 0, 0, 0, 1, 0,
0, 0, 1, 0, 1, 0, 1, 0,
0, 1, 1, 0, 0, 0, 1, 0,
0, 0, 0, 0, 1, 1, 0, 0,
0, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 1, 0, 1, 1,
1, 0, 0, 0, 1, 0, 0, 0,
};
Vector <char> path;
Int length = searchmaze (A, 8, 8, PATH );
If (length> 0 ){
Cout <"Shortest Path Length:" <length <Endl;
Cout <"The path :";
Copy (path. Begin (), path. End (), ostream_iterator <char> (cout ));
Cout <Endl;
} Else {
Cout <"can't reach the destination! "<Endl;
}
}
Program running result:
Shortest Path Length: 15
The path: rrrdddddrrddrr