题干
问题输入
一组数据,输入数据第1行为两个正整数m和n,m表示迷宫高度,n表示迷宫宽度,m<100,n<100;第2行为两个整数,分表表示起点的行列位置;第3行为两个整数,分别表示终点的行列位置;其后为m行数据,每行n个整数,表示迷宫对应位置的状态,0表示通路,1表示障碍。
问题输出
以三元组形式(上图)输出从起点到终点搜索到的第一条通路,没有则输出no
输入样例
8 8
1 1
8 8
0 0 1 0 0 0 1 0
0 0 1 1 0 0 1 0
0 0 0 0 1 1 0 0
0 1 1 1 0 0 0 0
0 0 0 1 1 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 1 0 0 0 0 0 0
输出样例
(1,1,1),(1,2,2),(2,2,2),(3,2,3),(3,1,2),(4,1,2),(5,1,1),(5,2,1),(5,3,2),(6,3,1),(6,4,1),(6,5,2),(7,5,2),(8,5,1),(8,6,1),(8,7,1),(8,8,1)
问题分析
初看题目,可以用栈记录已经走过的通路,当走不通时退栈,考虑上一步,在进行判断,利用穷举法进行探索(深度优先搜索)。用二维数组来储存迷宫,同时用一个和迷宫同样大的数组来标记该坐标是否走过。对于东南西北的方向判定,用两个数组来替换(具体看代码)。为了解决边界问题,设置地图时,可以在地图外面多加一圈1(设置一圈边界)。DFS不详细写,后面会专门写一个博客区分DFS和BFS。记录完入栈后,最后对栈进行逆转,即为路径。最后在注意一下输出格式,和逗号位置。
代码实现
//迷宫问题
#include<iostream>
#include<stack>
using namespace std;
int dy[4]={1,0,-1,0};//右下左上
int dx[4]={0,1,0,-1};
int s1,s2,o1,o2;
int maze[105][105];
int v[105][105]={0};//用于标记是否走过,1走过了
struct point{
int x;
int y;
int d;
};//创建栈的节点
stack<point> Dfs(stack<point> s){
if(s.empty()){
return s;
}//找不到出口
if(s.top().x==o1&&s.top().y==o2){
//找到出口
return s;
}
int x=s.top().x;
int y=s.top().y;
//查找当前位置的四个方向
point temp;//创建一个temp,表示即将入栈的坐标
for(int k=0;k<4;k++){
int tx,ty;
tx=x+dx[k];
ty=y+dy[k];
temp.x=tx;
temp.y=ty;
//考虑走过了的情况
//考虑如何往下继续。qwq
if(maze[tx][ty]==0&&v[tx][ty]==0){
s.top().d=k+1;
s.push(temp);
v[tx][ty]=1;
return s=Dfs(s);
//v[tx][ty]=0;
}
else{
if(k==3){
s.pop();
return s=Dfs(s);
}
}
}
}
stack<point> change(stack<point> s){
stack<point> p;
point q;
while(!s.empty()){
q=s.top();
p.push(q);
s.pop();
}
return p;
}
int main(){
int m,n;
cin>>m>>n;
cin>>s1>>s2;
cin>>o1>>o2;
for(int i=0;i<m+2;i++){
for(int j=0;j<n+2;j++){
maze[i][j]=1;
v[i][j]=0;
}
}//地图全部置1
for(int i=1;i<m+1;i++){
for(int j=1;j<n+1;j++){
cin>>maze[i][j];
}
}//输入迷宫
// for(int i=0;i<m+2;i++){
// for(int j=0;j<n+2;j++){
// cout<<maze[i][j];
// }
// cout<<endl;
// }//输出迷宫检验输入是否有问题
stack<point> l;
point st;
st.x=s1;st.y=s2;
l.push(st);
v[s1][s2]=1;
l=Dfs(l);
int len=l.size();//记录路径长度
if (len==0)//判断是否找到
{
cout<<"no";
}
else{
l.top().d=1;//到达终点后给终点的下个方向标记为1
//逆转栈
l=change(l);
for(int i=0;i<len;i++){
cout<<"("<<l.top().x<<","<<l.top().y<<","<<l.top().d<<")";
l.pop();
if(!l.empty()) cout<<",";
}
}
return 0;
}
总结
1,递归呀递归,哎,老是在这上面犯错,一定要注意递归返回结果后的运行,又因为小问题debug了一万年(qwq)。
2,为了方便,很多都设置的是全局变量,现在的水平只知道这样不好,但也不太会改进。有大佬可以指正一下。