问题:给指定的入口与出口,求该迷宫的通路。
思想:
1,我们要考虑越界问题。
2,我们要试探下一个位置是否可以通过,若这个位置上下左右都不能通过,则返回上一个位置。再去下一个位置。
代码的实现:
//建立一个存放坐标的结构体
struct Pos
{
size_t _row;
size_t _col;
};
template<size_t M, size_t N>
class Maze
{
public:
//初始化迷宫
//Maze(int maze[][N])
Maze(int* maze)
{
for (size_t i = 0; i < M; ++i)
{
for (size_t j = 0; j < N; ++j)
{
//_maze[i][j] = maze[i][j];
_maze[i][j] = maze[i*N+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;
if (!shortPath.empty())
{
cout<<"最短路径长度:"<<shortPath.size()<<" 出口";
stack<Pos> tmp = shortPath;
while (!tmp.empty())
{
Pos& top = tmp.top();
printf("[%d,%d]<-", top._row, top._col);
tmp.pop();
}
cout<<"入口"<<endl;
}
}
//查看下一个位置是否越界或合法
bool CheckAccess(Pos next)
{
if (next._row < M && next._col < N
&& _maze[next._row][next._col] == 0)
{
return true;
}
return false;
}
//判断下一个位置(非递归)
bool GetPath(Pos entry)
{
Pos cur, next;
cur = entry;
stack<Pos> path;//建立一个栈
path.push(entry);//将入口压入栈中
while (!path.empty())//如果这个栈不为空
{
cur = path.top(); // 取当前的栈顶
_maze[cur._row][cur._col] = 2;//并将当前的位置的内容变为2表示走过的。
if (cur._row == M-1)//如果当前走到最后一行,则找到通路
{
return true;
}
// 上
next = cur;
next._row -= 1;
if (CheckAccess(next))
{
path.push(next);
continue;
}
// 下
next = cur;
next._row += 1;
if (CheckAccess(next))
{
path.push(next);
continue;
}
// 右
next = cur;
next._col += 1;
if (CheckAccess(next))
{
path.push(next);
continue;
}
// 左
next = cur;
next._col -= 1;
if (CheckAccess(next))
{
path.push(next);
continue;
}
// 回溯
path.pop();//如果上下左右都不通,则返回上一个位置
}
return false;
}
//递归判断下一个位置是否可以走
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._row += 1;
if (CheckAccess(next))
{
GetPathR(next);
}
next = entry;
next._col += 1;
if (CheckAccess(next))
{
GetPathR(next);
}
next = entry;
next._col -= 1;
if (CheckAccess(next))
{
GetPathR(next);
}
}
bool CheckAccess(Pos cur, Pos next)
{
if ((next._row < M && next._col < N)
&& (_maze[next._row][next._col] == 0
|| _maze[next._row][next._col] > _maze[cur._row][cur._col]))
{
return true;
}
return false;
}
//求最短路径
void GetShortPath(Pos entry, stack<Pos>& path)
{
path.push(entry);//将入口压栈
if (entry._row == M-1)//如果走到了最后一行,则找到了通路
{
if (shortPath.empty() || path.size() < shortPath.size())//如果最短路径为空或者path的路径小于shortPath
{
shortPath = path;//将path路径给shortPath路径
}
cout<<"找到一个出口"<<"["<<entry._row<<","<<entry._col<<"]"<<endl;
path.pop();
return;
}
// 上
Pos next;
next = entry;
next._row -= 1;
if (CheckAccess(entry, next))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col]+1;
GetShortPath(next, path);
}
// 右
next = entry;
next._col += 1;
if (CheckAccess(entry, next))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col]+1;
GetShortPath(next, path);
}
// 下
next = entry;
next._row += 1;
if (CheckAccess(entry, next))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col]+1;
GetShortPath(next, path);
}
next = entry;
next._col -= 1;
if (CheckAccess(entry, next))
{
_maze[next._row][next._col] = _maze[entry._row][entry._col]+1;
GetShortPath(next, path);
}
path.pop();
}
protected:
int _maze[M][N];
stack<Pos> shortPath;
};
//测试代码
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},
{2,0,0,0,0,0,0,1,1,1},
{1,1,0,1,1,1,0,1,1,1},
{1,1,0,0,0,0,0,1,1,1},
{1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1},
{1,1,1,1,1,0,1,1,1,1}
};
/*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((int*)mazeArray);
maze.Print();
Pos entry = {2, 0};
stack<Pos> path;
maze.GetShortPath(entry, path);
maze.Print();
}