迷宫问题

题目描述
迷宫是一个二维矩阵,其中1为墙,0为路,3为入口,4为出口.要求从入口开始,从出口结束,按照 下,左,上,右 的顺序来搜索路径.

输入
迷宫宽度w 迷宫高度h
迷宫第一行
迷宫第二行

迷宫第h 行

输出
入口横坐标1 入口纵坐标1
横坐标2 纵坐标2
横坐标3 纵坐标3
横坐标4 纵坐标4

横坐标n-1 纵坐标n-1
出口横坐标n 出口纵坐标n
样例输入
8 10
1 1 1 1 1 1 1 1
1 0 1 1 0 1 0 1
1 0 1 0 0 1 0 1
1 1 0 3 1 0 1 1
1 0 0 1 0 0 4 1
1 0 0 0 0 1 1 1
1 0 1 0 0 1 0 1
1 0 1 0 0 0 1 1
1 1 1 1 0 0 0 1
1 1 1 1 1 1 1 1
样例输出
3 3
2 3
2 4
2 5
3 5
3 6
3 7
4 7
4 6
4 5
4 4
5 4
6 4

这是一道比较经典练习栈的题目,emmm,我写这题时一开始的思路也是想着用深搜写,然后深搜不太会写,然后我就想了一下决定用栈写,后面学习了深搜又用深搜写了一遍,然后我在这里贴出使用栈和使用深搜写的代码,有点奇怪,深搜竟然没有超时,还通过了。首先肯定是栈的代码

#include <iostream>
#include<stdio.h>
#include<cstring>
using namespace std;
int maze[1005][1005],vis[1005][1005];//迷宫地图和迷宫标记
int top,w,h;
int dx[4]= {1,0,-1,0};//四个方向
int dy[4]= {0,-1,0,1};
struct point
{
    int x;
    int y;
} s[1005*16];//这个挺重要的,我们使用一个栈来存储我们经过的路径
void dfs()
{
    
    while(1)
    {
        bool flag =false;//先设置标志看能否走通
        for(int i=0; i<4; i++)
        {
            int nx=s[top].x+dx[i];
            int ny=s[top].y+dy[i];
            if(nx<0||nx>=h||ny<0||ny>=w) continue;
            if(maze[nx][ny]==4)
            {
                for(int j=0; j<=top; j++)
                {
                    printf("%d %d\n",s[j].y,s[j].x);
                }
                printf("%d %d\n",ny,nx);
                return ;
            }
            if(maze[nx][ny]==0&&vis[nx][ny]==0)
            {
                top++;
                flag = true;
                vis[nx][ny]=1;
                s[top].x=nx;
                s[top].y=ny;
                break;
            }
        }
        if(!flag)
            top--;
    }
}
int main()
{
    int x1,y1;
    scanf("%d%d",&w,&h);
    for(int i=0; i<h; i++)
        for(int j=0; j<w; j++)
        {
            scanf("%d",&maze[i][j]);
            if(maze[i][j]==3)
            {
                x1=i;
                y1=j;
            }
        }
    top=0;
    s[top].x=x1;
    s[top].y=y1;
    memset(vis,0,sizeof(vis));
    dfs();

    return 0;
}

这是使用栈的代码,说使用栈其实也没太用到栈,感觉主要使用的还是循环,只是使用栈来存储走过的路径,这确实是由于本人当时不会深搜,只能用循环来弄。后面使用深搜来写,下面贴出深搜的代码。

#include <iostream>

using namespace std;
int w,h;
typedef struct point{
int x;
int y;
}Point;
Point p[100005];
int top=0;
int a[1005][1005];
int vis[1005][1005];
int moves[4][2]= {{1,0},{0,-1},{-1,0},{0,1}};
bool dfs(int x1,int y1)
{

    if(a[x1][y1]==4)
    {
        return true;
    }
    for(int i=0; i<4; i++)
    {
        int nx=x1+moves[i][0];
        int ny=y1+moves[i][1];
        if(nx>=0&&nx<h&&ny>=0&&ny<w&&a[nx][ny]!=1&&vis[nx][ny]==0)
        {
            top++;
            p[top].x=nx;
            p[top].y=ny;
            vis[nx][ny]=1;
            if(dfs(nx,ny))
            return true;
        }
    }
    top--;
    return false;

}

int main()
{

    int x1,y1,x2,y2;
    cin>>w>>h;
    for(int i=0; i<h; i++)
        for(int j=0; j<w; j++)
        {
            cin>>a[i][j];
            if(a[i][j]==3)
            {
                x1=i;
                y1=j;
            }
            if(a[i][j]==4)
            {
                x2=i;y2=j;
            }
        }
    vis[x1][y1]=1;
    p[0]= {x1,y1};
    dfs(x1,y1);
    for(int i=0;i<top;i++)
    {
       cout<<p[i].y<<" "<<p[i].x<<endl;
    }
    cout<<y2<<" "<<x2<<endl;

    return 0;
}

深搜的代码相对来说比较简洁,理解起来比较简单,如果用循环来写代码量相对来说比较大。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值