A - Maze迷宫问题

题目:

东东有一张地图,想通过地图找到妹纸。地图显示,0表示可以走,1表示不可以走,左上角是入口,右下角是妹纸,这两个位置保证为0。既然已经知道了地图,那么东东找到妹纸就不难了,请你编一个程序,写出东东找到妹纸的最短路线。

Input:

输入是一个5 × 5的二维数组,仅由0、1两数字组成,表示法阵地图。

Output:

输出若干行,表示从左上角到右下角的最短路径依次经过的坐标,格式如样例所示。数据保证有唯一解。

Sample Input:

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

Sample Output:

(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)

Hint:

坐标(x, y)表示第x行第y列,行、列的编号从0开始,且以左上角为原点。另外注意,输出中分隔坐标的逗号后面应当有一个空格。

题目分析:

这是一道迷宫问题,该问题可以转换为在一个二维平面直角坐标系中,如何从原点(0,0)到达终点(5,5)。将一个点的坐标(x,y)用结构体point来表示。

要找到最短路线,考虑bfs宽度搜索算法,即利用队列,遍历所有可以通过的点组成的所有路线,找出最短路线并输出。当队列不为空时,取出队列首元素,特判终点是否已到达,若已到达停止搜索。否则从该点向外走,根据方格的特点,向外走无非上下左右四个方向,所以此处用到常量数组dx={0,0,1,-1},dy={1,-1,0,0}来表示该点向外走的所有可能性。然后判断其合法性以及用二维数组vis[ ][ ]判断是否曾经到达,若合法且未曾到达,则该方向可行,将其存入队列内,并用数组pre[ ]记录该方向是哪个点走过来的。

因为题目要求输出所有路线,所以可以考虑利用递归逆序输出pre[ ]的方式。因为(0,0)就是起点,没有前一个点,所以当路线点不为(0,0)的执行递归,否则直接输出(0,0)即可。

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
const int maxn=1e3+5;
using namespace std;
struct point//坐标 
{
    int x;
    int y;
};
int a[5][5];//矩阵 
bool vis[5][5];//标记是否已到达 
point pre[maxn][maxn];//前一个节点 
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
queue<point> q;//队列 
void bfs()
{
    memset(vis,false,sizeof(vis));//初始化为flase 
    memset(pre,0,sizeof(pre));
    point s;
    s.x=s.y=0;//起始点 
    q.push(s);
    vis[s.x][s.y]=true;
    while(!q.empty())//当队列不为空时 
    {
        point temp=q.front();//取出队列首元素
        q.pop(); 
        if(temp.x==4 && temp.y==4)//到达终点 
        {
             return ;
        }
        for(int i=0;i<4;i++) //向外走 
        {
  
            point next;
            next.x=temp.x+dx[i];
            next.y=temp.y+dy[i];
            if(next.x>=0&&next.x<=4&&next.y>=0&&next.y<=4&&!vis[next.x]  [next.y]&&a[next.x][next.y]!=1)
            {
                 vis[next.x][next.y]=true;//被标记为已访问 
                 pre[next.x][next.y]=temp;//前一个点
                 q.push(next); 
            }  
         } 
     }
}
void output(point t)//递归输出
{
         if(t.x!=0||t.y!=0)
	 {
	      output(pre[t.x][t.y]);
	      cout<<"("<<t.x<<", "<<t.y<<")"<<endl;  
	 }
	 else
	 {
	      cout<<"("<<0<<", "<<0<<")"<<endl;
	      return; 
	 }
}
int main()
{   
      for(int i=0;i<5;i++)
      {
	  for(int j=0;j<5;j++)
	  {
	      cin>>a[i][j];
	  }
      }
     bfs();
     point t;
     t.x=t.y=4;
     output(t);
     return 0; 
}

样例运行:

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值