POJ 3984 迷宫问题

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 22809 Accepted: 13292

Description

定义一个二维数组: 
int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
这是一道广搜+递归的题,前天做过一个迷宫的最短路的题,看到这个题的时候我觉得我会很快做出来,结果后来递归递了半天,前天做的是只要求最短路的步数,而这个要输出路径来,并且做的那个题是用pair状态做的,对队列掌握的并不深的我,有点懵逼,通过这个题,对队列了解的深了点!
用rear尾指针指向下一个,front指向头元素,就相当于我用rear这样一路记录下去,而遇到分岔路口的时候,front就起作用了,它可以先去标记一个支点,标记完了以后再去标记另一个支点,以此类推,保证不一路搜到底,而是横着搜,只可意会,不可言传啊,自己懂,但是讲不清楚敲打
#include<iostream>
using namespace std;
struct Node{
   int x;
   int y;
   int pre;
}queue[50];//建立一个50个格子的队列;
int a[5][5];//迷宫的地图
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//控制移动方向的数组
int vis[5][5];//标记
int front=0;//队头
int rear=0;//队尾 头指针指向头元素,尾指针指向队尾的下一个位置
void print(Node now)//输出
{
    int t=now.pre;
    if(t==-1)
    {
        cout<<"("<<now.x<<", "<<now.y<<")"<<endl;
    }
    else
    {
        print(queue[now.pre]);
        cout<<"("<<now.x<<", "<<now.y<<")"<<endl;
    }
}
//广搜
void bfs(int sx,int sy,int gx,int gy)
{
    queue[0].x=sx;
    queue[0].y=sy;//起点的坐标
    queue[0].pre=-1;//将初始结点[0,0]压入队列
    rear=rear+1;
    vis[0][0]=1;
    while(front<rear)//如果队列不为空
    {
        for(int i=0;i<5;i++)//搜索方向
        {
            int nx=queue[front].x+dx[i];
            int ny=queue[front].y+dy[i];
            if(nx>=0&&nx<5&&ny>=0&&ny<5&&vis[nx][ny]!=1&&a[nx][ny]!=1)//判断是否在地图里,是否被标记,是否撞墙
            {
                queue[rear].x=nx;
                queue[rear].y=ny;
                queue[rear].pre=front;
                vis[nx][ny]=1;
                rear++;
                if(nx==4&&ny==4)
                   return ;
            }
        }
        front++;
    }
}
int main()
{
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<5;j++)
        {
            cin>>a[i][j];
        }
    }
    bfs(0,0,4,4);
    print(queue[rear-1]);
    return 0;

}
二、用vector、pair做
#include <cstdio>
#include "stdlib.h"
#include "iostream"
#include "algorithm"
#include "string"
#include "cstring"
#include "queue"
#include "cmath"
#include <vector>
#include "map"
#include "set"
#define mj
#define db double
#define ll long long
using namespace std;
const int N=1e8+2;
const int mod=1e9+7;
const ll inf=1e16+10;
typedef pair<int,int> P;
vector<P> m;
queue<P> q;
P fa[12][12];

int  s[12][12];
int d[12][12];
int dx[4]= {1,0,-1,0},dy[4]= {0,1,0,-1};
void pt(P u)
{
    while(1)
    {
        m.push_back(u);//从后往前找父节点
        if(u==P(0,0)) break;//根节点
        u=fa[u.first][u.second];
    }
    for(int i=(int)m.size()-1; i>=0; i--) //从根节点开始依次输出路径
        printf("(%d, %d)\n",m[i].first,m[i].second);
}
void bfs()
{
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
        {
            d[i][j]=N;
        }
    }
    q.push(P(0,0));
    d[0][0]=0;
    while(q.size())
    {
        P p;
        p=q.front(),q.pop();
        if(p.first==4&&p.second==4)
        {
            pt(p);
            return;
        }
        for(int i=0; i<4; i++)
        {
            int nx=p.first+dx[i],ny=p.second+dy[i];
            if(0<=nx&&nx<5&&0<=ny&&ny<5&&!s[nx][ny]&&d[nx][ny]==N)
            {
                d[nx][ny]=d[p.first][p.second]+1;
                fa[nx][ny]=p;

                q.push(P(nx,ny));
            }
        }


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




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值