迷宫问题 POJ 3984 栈和bfs

题目大意是,给你一个二维数组,5*5的,这个图中有墙,现在让你找出从左上角到右下角的最短路径,并把路径输出;

  

分析,其实这道题的难点只有一个,就是如何把最短路径按顺序输出,找到最短路径其实只需要bfs就好

我的做法是,使用一个逆向的方向数组,和一个栈

比如bfs的方向数组是{1,0},{-1,0},{0,1},{0,-1} 那么逆向数组依次就是{-1,0},{1,0},{0,-1},{0,1}这样就可以通过最后一个点来复原他的上一个状态,最后让你通过逆向数组得到的坐标跟栈中存放的坐标进行比较,如果相同那么栈中的那个点就是这个点的上一个状态

代码

#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>

using namespace std;
int vis[5][5];
int mp[5][5];
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
int fdir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//逆向数组
int n;
struct summer
{
    int x,y;
    int i;//记录这个点是经过那种变化得到的,方便回来使用逆向数组来复原
    int step;
    friend bool operator < (summer a,summer b)
    {
        return  a.step>b.step;
    }
};
vector<summer>oj;
stack<summer>iron;
void line(summer a)//通过这个函数,来得到每一个点的上一个状态
{
    summer b;
    a.x+=fdir[a.i][0];//逆向过程
    a.y+=fdir[a.i][1];
   while(!iron.empty())
   {
       b=iron.top();
       iron.pop();
       if(b.x==a.x&&b.y==a.y)//判断经过你逆向复原的坐标在不在栈中,栈存放的是bfs时经过的所有坐标;
       {
           a.x=b.x;
           a.y=b.y;
           a.i=b.i;
           a.x+=fdir[a.i][0];
           a.y+=fdir[a.i][1];
           oj.push_back(b);//如果相同,压入vector中,以便输出路线;
       }
   }
   for(int i=oj.size()-1;i>=0;i--)
   {
       printf("(%d, %d)\n",oj[i].x,oj[i].y);
   }
   printf("(4, 4)\n");//不要忘了4,4这个坐标,因为这个点并没有被压入栈中
}

void bfs()
{
    priority_queue<summer>que;
    summer a,a2;
    a.x=0;
    a.y=0;
    a.i=0;
    a.step=0;
    vis[0][0]=1;
    que.push(a);
    while(!que.empty())
    {
        a=que.top();
        iron.push(a);//这个就是把bfs的所有路线上的点全部压入栈中,为了后面与复原坐标比较得出正确的坐标
        que.pop();
        if(a.x==4&&a.y==4)
        {
            line(a);
            break;
        }
        for(int i=0;i<4;i++)
        {
            a2.x=a.x+dir[i][0];
            a2.y=a.y+dir[i][1];
            a2.i=i;
            if(a2.x<0||a2.y<0||a2.x>=5||a2.y>=5||vis[a2.x][a2.y]==1) continue;
            if(mp[a2.x][a2.y]!=1)
            {
                a2.step++;
                vis[a2.x][a2.y]=1;
                que.push(a2);
            }
        }
    }
}

int main()
{
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            scanf("%d",&mp[i][j]);
        }
    }
    bfs();
    return  0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值