#include <iostream>
using namespace std;
#include <stack>
struct Pos//定义坐标点
{
size_t _row;
size_t _col;
};
template<size_t M, size_t N>
class Maze
{
protected:
int _maze[M][N];
stack<Pos> shortPath;
public:
Maze(int maze[][N])//构造函数,初始化对象
{
for (size_t i = 0; i < M; i++)
{
for (size_t j = 0; j < N; j++)
{
_maze[i][j] = maze[i][j];
}
}
}
void print()//打印二维矩阵函数
{
for (size_t i = 0; i < M; i++)
{
for (size_t j = 0; j < N; j++)
{
cout << _maze[i][j] << " ";
}
cout << endl;//每行完了换行
}
cout << endl;//最后换行
}
bool CheckAccess(Pos next,Pos entry)//探测next位置是否可通
{
if (next._row < M && next._col < N &&
((_maze[next._row][next._col] == 0)
||(_maze[next._row][next._col]>_maze[entry._row][entry._col])))//坐标点合法且这点值为0
{
return true;
}
return false;
}
bool GetPath(Pos entry)//找通路
{
//上下左右四个方向探测
Pos cur, next;//定义当前点、下一个点的坐标
cur = entry;//让cur来到入口
stack<Pos> path;
path.push(entry);
while (!path.empty())
{
cur = path.top(); //
_maze[cur._row][cur._col] = 2;// 将走过的路设置为2,如果 程序每个来到这,说明是continue上来的,next
////出口只针对这道题?
if (cur._row == M - 1)//出口
{
return true;
}
//上
next = cur;//让next也先指向入口
next._row -= 1;
if (CheckAccess(next))//上可通
{
//cur = next;//再以可通的点作为入口
path.push(next); //
continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
}
//右
next = cur;//让next恢复到入口
next._col += 1;
if (CheckAccess(next))//上可通
{
//cur = next;//再以可通的点作为入口
path.push(next);
continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
}
//下
next = cur;//让next恢复到入口
next._row += 1;
if (CheckAccess(next))//上可通
{
//cur = next;//再以可通的点作为入口
path.push(next);
continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
}
//左
next = cur;//让next恢复到入口
next._col -= 1;
if (CheckAccess(next))//上可通
{
//cur = next;//再以可通的点作为入口
path.push(next);
continue;//只要一个方向可通,则不需要判断下一个,即后面的语句不再被执行
}
//回溯
path.pop();
}
return false;
}
void GetShortPath(Pos entry, stack<Pos>& path)//递归找通路坐标点
{
path.push(entry);
if (entry._row == M - 1)
{
if (shortPath.empty() || path.size() < shortPath.size())
{
shortPath = path; // ortPath最短路径
}
cout << "找到一个出口" << "[" << entry._row << "," << entry._col << "]" << endl;
if (!shortPath.empty())
{
cout << "最短路径:出口";
stack<Pos> tmp = shortPath;
while (!tmp.empty())
{
Pos& top = tmp.top();
printf("[%d,%d]<-", top._row, top._col);
tmp.pop();
}
cout << endl;
}
cout << endl;
return;
}
Pos next;
//上
next = entry;
next._row -= 1;
if (CheckAccess(next,entry))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col]+1;
GetShortPath(next, path);
}
//右
next = entry;
next._col += 1;
if (CheckAccess(next, entry))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col] + 1;
GetShortPath(next, path);
}
//下
next = entry;
next._row += 1;
if (CheckAccess(next, entry))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col] + 1;
GetShortPath(next, path);
}
//左
next = entry;
next._col -= 1;
if (CheckAccess(next, entry))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col] + 1;
GetShortPath(next, path);
}
path.pop();
}
void GetPathR(Pos entry)//递归找通路
{
_maze[entry._row][entry._col] = 2;
if (entry._row == M - 1)
{
cout << "找到一个出口" << "[" << entry._row << "," << entry._col << "]" << endl;
return;
}
Pos next;
//上
next = entry;
next._row -= 1;
if (CheckAccess(next))
{
GetPathR(next);
}
//右
next = entry;
next._col += 1;
if (CheckAccess(next))
{
GetPathR(next);
}
//下
next = entry;
next._row += 1;
if (CheckAccess(next))
{
GetPathR(next);
}
//左
next = entry;
next._col -= 1;
if (CheckAccess(next))
{
GetPathR(next);
}
}
};
void TestMaze()
{
int mazeArray[10][10] = { { 1,1,1,1,1,1,1,1,1,1 },
{ 1,1,1,1,1,1,1,1,1,1 },
{ 0,0,0,1,1,1,1,1,1,1 },
{ 1,1,0,1,1,1,1,1,1,1 },
{ 1,1,0,0,0,0,1,1,1,1 },
{ 1,1,0,1,1,0,1,1,1,1 },
{ 1,1,0,1,1,0,1,1,1,1 },
{ 1,1,0,1,1,0,1,1,1,1 },
{ 1,1,0,1,1,0,1,1,1,1 },
{ 1,1,0,1,1,0,1,1,1,1 }
};
Maze<10, 10> maze(mazeArray);//用已知数组mazeArray初始化对象maze
maze.print();
Pos entry = { 2,0 };
//if (maze.GetPath(entry))
//{
// cout << "找到通路" << endl;
//}
//else
//{
// cout << "找不到通路" << endl;
//}
//maze.GetPath(entry);//从入口进去找通路
//maze.GetPathR(entry);
stack<Pos> path;
maze.GetShortPath(entry, path);
maze.print();
}
int main()
{
TestMaze();
return 0;
}