POJ3984【迷宫问题】

前言:
相信大家都玩过迷宫游戏,它的游戏规则就是从起点开始出发到达终点,在ACM中,它是一道很好的搜题题,其可以用BFS和DFS两种方法解决,接下来我们讨论这两种解法的异同点。
DFS:即深度优先搜索,它的特点是一直递归到结束,在往回遍历,很像数据结构中的栈;所以,如果用此解法不一定能得到迷宫的最短路径,因为它会把所有可行路径(即能到达终点的)都遍历一遍,特别要注意的是,一定要做好标记,不然在某一点会陷进死循环(重复在一点递归操作),然后还要记得回溯,即递归后还原该点为可行点,不然你只能得到唯一一条路径,因为你把到达这条终点的路径封死了,其他路径哪还有机会到达终点。最后总结,DFS的优点:1、所有路径都走一遍。2、最长路径,最短路径都能找到。缺点:1、思维难度比BFS大。2、代码相对复杂。

BFS:即广度优先搜索,它的特点是一层层遍历,很像数据结构的队列;一般用此法可以找到问题的最优解,但要注意的是,也一定要做好标记,即遍历过的点不能重新入队列了,不然也是死循环,与DFS不同之处在于,它不需要回溯,因为它是从某一点一直向外扩展(没有递归哪来的回溯)。最后总结,BFS的优点:1、找最最优解。2、思维难度低。缺点:没有像DFS一样万能。

附代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;

typedef long long LL;
const int MAXN=5;
const int INF=0x3f3f3f3f;
bool vis[MAXN][MAXN];
int map[MAXN][MAXN];
int dir[4][2]= { {0,1},{1,0},{0,-1},{-1,0} };
struct node
{
    int x,y,step;
    node()
    {
        this->x=0;
        this->y=0;
    }
    node(int x,int y)
    {
        this->x=x;
        this->y=y;
    }
    node(int x,int y,int s)
    {
        this->x=x;
        this->y=y;
        this->step=s;
    }
};
node fa[MAXN][MAXN];//记录父节点的属性
queue<node>qu;

//判断该点是否能走
bool check(int x,int y)
{
    if(x<0||x>4||y<0||y>4)
        return false;
    if(vis[x][y]||map[x][y]==1)
        return false;
    return true;
}

void output(node e);
//int ans=0;//记录路径数
//void DFS(node now)
//{
//    if(now.x==4&&now.y==4){
//        ans++;
//        output(node(4,4));
//        cout<<"行走步数:"<<now.step<<endl;
//        cout<<endl;
//        return ;
//    }
//    for(int i=0;i<4;i++){
//        int xx=now.x+dir[i][0];
//        int yy=now.y+dir[i][1];
//        int ss=now.step+1;
//        if(!check(xx,yy))
//            continue;
//        vis[xx][yy]=true;
//        fa[xx][yy]=now;
//        DFS(node(xx,yy,ss));
//        vis[xx][yy]=false;
//    }
//}


void BFS(node now)
{
    qu.push(now);
    vis[now.x][now.y]=true;
    while(!qu.empty())
    {
        node curr=qu.front();
        qu.pop();
        if(curr.x==4&&curr.y==4){
            output(curr);
            return ;
        }
        for(int i=0; i<4; i++)
        {
            int xx=curr.x+dir[i][0];
            int yy=curr.y+dir[i][1];
            if(!check(xx,yy))
                continue;
            vis[xx][yy]=true;
            fa[xx][yy]=curr;//指向上一个节点
            node p(xx,yy);
            qu.push(p);
        }
    }
}

//递归输出路径
void output(node e)
{
    if(e.x==0&&e.y==0)
    {
        cout<<"("<<0<<", "<<0<<")->";
        return ;
    }
    output(fa[e.x][e.y]);
    cout<<"("<<e.x<<", "<<e.y<<")";
    if(e.x!=4||e.y!=4) cout<<"->";
}

int main()
{
    memset(vis,false,sizeof(vis));
    for(int i=0; i<5; i++)
        for(int j=0; j<5; j++)
            cin>>map[i][j];
    node b(0,0,0);
    BFS(b);
//    DFS(b);
//    cout<<"到达终点路径数:"<<ans<<endl;
    return 0;
}


题目链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demo2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值