题目描述
给出一个N*N的迷宫矩阵示意图,从起点[0,0]出发,寻找路径到达终点[N-1, N-1]
要求使用堆栈对象来实现,具体算法参考课本3.2.4节51页
输入
第一行输入t,表示有t个迷宫
第二行输入n,表示第一个迷宫有n行n列
第三行起,输入迷宫每一行的每个方格的状态,0表示可通过,1表示不可通过
输入n行
以此类推输入下一个迷宫
输出
逐个输出迷宫的路径
如果迷宫不存在路径,则输出no path并回车
如果迷宫存在路径,将路径中每个方格的x和y坐标输出,从起点到终点,每输出四个方格就换行,最终以单词END结尾,具体格式参考示范数据
输出的代码参考如下:
//path是保存路径的堆栈,堆栈中每个元素都包含x坐标和y坐标,用属性xp和yp表示
//path1是一个临时堆栈,把path的数据倒序输出到path1,使得路径按正序输出
if (!path.empty()) //找到路径
{ //......若干代码,实现path的数据导入path1
i=0; //以下是输出路径的代码
while (!path1.empty())
{ cpos = path1.top();
if ( (++i)%4 == 0 )
cout<<'['<<cpos.xp<<','<<cpos.yp<<']'<<"--"<<endl;
else
cout<<'['<<cpos.xp<<','<<cpos.yp<<']'<<"--";
path1.pop();
}
cout<<"END"<<endl;
}
else
cout<<"no path"<<endl; //找不到路径输出no path
输入样例1
2
8
0 0 0 1 1 1 1 1
1 0 0 0 1 0 0 1
1 0 0 0 1 0 0 0
1 1 0 0 0 0 0 1
0 0 1 1 0 1 1 0
0 0 0 0 0 0 1 1
1 1 1 1 1 0 0 1
0 0 0 0 1 0 0 0
7
0 0 0 1 1 1 1
1 0 0 1 0 0 1
1 0 0 1 0 0 0
1 1 0 0 0 0 1
0 0 1 1 0 1 0
1 0 0 0 0 1 0
0 0 0 0 1 1 0
这里要注意第一位是1的情况!
输出样例1
[0,0]--[0,1]--[0,2]--[1,2]--\n
[1,3]--[2,3]--[3,3]--[3,4]--\n
[4,4]--[5,4]--[5,5]--[6,5]--\n
[6,6]--[7,6]--[7,7]--END\n
no path\n
#include<iostream>
#include<stack>//堆栈头文件
using namespace std;
struct position {//结构体,关于x,y二维坐标
int x;
int y;
};
class Maze {//迷宫
public:
int** maze;//迷宫矩阵
int size;
stack<position>Path;//建立二维的堆栈,保存路径的堆栈,因为要保存x,y两个数字,单纯用int无法满足,只能创建结构体对象
Maze(int n) {
size = n;
maze = new int* [n];
for (int i = 0; i < n; i++) {//行
maze[i] = new int[n];//动态创建每一行多少列
}
for (int i = 0; i < n; i++) {//行
for (int j = 0; j < n; j++) {//列
cin >> maze[i][j];//输入
}
}
}
int Goto();
};
int Maze::Goto() {
if (maze[0][0] == 1) {//特殊情况,第一个数字就是1,此时整个迷宫无效
cout << "no path" << endl;
return 0;
}
//此时,可以知道【0,0】一定等于0
Path.push({ 0,0 });//花括号,用于压入多个元素!!!
maze[0][0] = 1;//压入后,可以将值改为1,表示不走回头路。
int i = 0, j = 0;//重新设置为0,来确定下一个走向,走0,1;还是1,0;还是1,1.
while (1) {//一直循环,除非为空,或者走到了终点
if (Path.empty() || (i + 1 == size && j + 1 == size)) {
break;//跳出循环
}
//判断走向(右下左上)
if (j + 1 < size && maze[i][j + 1] == 0) {//右边有路,并且可以走
maze[i][j + 1] = 1;//准备右走,把它标为1,以后都不能走这条路,用于后面的退回
Path.push({ i,++j });//把当前位置压入栈
}
else if (i + 1 < size && maze[i + 1][j] == 0) {//向下
maze[i + 1][j] = 1;
Path.push({ ++i,j });
}
else if (j - 1 >= 0 && maze[i][j - 1] == 0) {//左边有路,并且能走
maze[i][j - 1] = 1;//准备左走,标为1
Path.push({ i,--j });
}
else if (i - 1 >= 0 && maze[i - 1][j] == 0) {//向上
maze[i - 1][j] = 1;
Path.push({ --i,j });
}
else {//四个方向都走不了
i = Path.top().x;//退回一格,找到当前的x
j = Path.top().y;//退回一格,找到此时的y
//如果此时的四个方向 没有其他路走
if (!((j + 1 < size && maze[i][j + 1] == 0) || (i + 1 < size && maze[i + 1][j] == 0) || (j - 1 >= 0 && maze[i][j - 1] == 0) || (i - 1 >= 0 && maze[i - 1][j] == 0))) {
Path.pop();//没有其他的路,出栈
}
}
}
//输出
if (!Path.empty()) //找到路径
{ //......若干代码,实现path的数据导入path1
stack<position>path1;//使Path正序输出!
while (!Path.empty()) {
path1.push(Path.top());//把Path的栈顶输入path1
Path.pop();//弹出,此时top向下移动一位
}
i = 0; //以下是输出路径的代码
while (!path1.empty())
{
if ((++i) % 4 == 0) {//每4个数据为一行
cout << '[' << path1.top().x << ',' << path1.top().y << ']' << "--" << endl;//每行输到第四个数据后面要换行。
}
else {
cout << '[' << path1.top().x << ',' << path1.top().y << ']' << "--";//为第1,2,3个数据,只需要输出本身,不需要换行。
}
//弹出当前的数据
path1.pop();
}
//全部输出完
cout << "END" << endl;
}
else {
cout << "no path" << endl; //找不到路径输出no path
}
return 0;
}
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
Maze mymaze(n);//输入迷宫矩阵
mymaze.Goto();
}
return 0;
}