数据结构入门(4)迷宫问题

题干

问题输入

一组数据,输入数据第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,为了方便,很多都设置的是全局变量,现在的水平只知道这样不好,但也不太会改进。有大佬可以指正一下。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
迷宫问题是一个经典的数据结构课程设计问题,目标是设计一个算法,找到从迷宫的起点到终点的路径。迷宫可以用一个方阵[m,n]表示,其中0表示可以通过的路径,1表示不可通过的路径。我们需要从左上角[1,1]进入迷宫,寻找一条从右下角[m,n]出去的路径。 以下是一个可能的解决方案: 1. 使用深度优先搜索算法(DFS): - 创建一个空的路径列表,用于存储找到的路径。 - 创建一个空的访问列表,用于记录已经访问过的位置。 - 定义一个递归函数,该函数接受当前位置和当前路径作为参数。 - 在递归函数中,首先检查当前位置是否为终点,如果是,则将当前路径添加到路径列表中并返回。 - 如果当前位置不是终点,则将当前位置添加到访问列表中,并继续向四个方向进行探索。 - 对于每个可行的方向,递归调用函数,并将当前位置和路径作为参数传递。 - 在递归调用返回后,将当前位置从访问列表中移除。 - 最后,返回路径列表中的第一条路径作为结果。 2. 使用广度优先搜索算法(BFS): - 创建一个空的路径列表,用于存储找到的路径。 - 创建一个空的队列,用于存储待探索的位置。 - 创建一个空的访问列表,用于记录已经访问过的位置。 - 将起点位置添加到队列中,并将其标记为已访问。 - 进入循环,直到队列为空: - 从队列中取出一个位置。 - 检查该位置是否为终点,如果是,则将路径添加到路径列表中并继续下一次循环。 - 如果该位置不是终点,则将其标记为已访问,并将其可行的相邻位置添加到队列中。 - 返回路径列表中的第一条路径作为结果。 这两种算法都可以用来解决迷宫问题,具体选择哪种算法取决于实际需求和迷宫的规模。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值