【c++】蓝桥杯1216题:走迷宫(bfs)

给定一个 N×M 的网格迷宫 G。G 的每个格子要么是道路,要么是障碍物(道路用 1 表示,障碍物用 0 表示)。

已知迷宫的入口位置为 (x_{1},y_{1}),出口位置为 (x_{2}​,y_{2}​)。问从入口走到出口,最少要走多少个格子。

输入描述

输入第 1 行包含两个正整数 N,M,分别表示迷宫的大小。

接下来输入一个 N×M 的矩阵。若 G_{i,j}=1 表示其为道路,否则表示其为障碍物。

最后一行输入四个整数 ​x_{1},y_{1}​,x_{2}​,y_{2}​,表示入口的位置和出口的位置。

1\leqslant N,M\leqslant 10^{2},0\leqslant G_{i,j}\leqslant 1,1\leqslant x_{1},x_{2}\leqslant N,1\leqslant y_{1},y_{2}\leqslant M

输出描述

输出仅一行,包含一个整数表示答案。

若无法从入口到出口,则输出 -1。

输入输出样例

示例 1

输入

5 5 
1 0 1 1 0
1 1 0 1 1 
0 1 0 1 1
1 1 1 1 1
1 0 0 0 1
1 1 5 5 

输出

8

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

编译环境:Dev-Cpp 5.11 TDM-GCC 4.9.2

啰嗦版(含注释)

#include <bits/stdc++.h>
using namespace std;
int N,M,count99=0,len=1;//count99为记录答案的计数器,由于count与库函数的某个关键字重名,故不能直接使用count//len用于记录bfs每一层的坐标点数量,辅助count99记录答案
//关于取名:找一套能够跟关键字不重名的取名规则比如大写之类的(虽然我还没找--),可以减少以后debug的时间
int x1,yemmm,x2,y2;//入口坐标x1,y1,出口坐标x2,y2
//取名yemmm同样是因为y1也能重名,emmm,看来取个好名字势在必行了
pair<int,int> ex1;//临时存储一对数据,也可以在函数中定义
int Map[110][110];//存储迷宫
int vis[110][110];//记录迷宫中各点的访问情况
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
//朝上、下、左、右四个方向走时,坐标对应的变化
queue<pair<int,int> > q;//队列q:存放bfs过程中各坐标点

int check(int x,int y)
{
  if(x>N||x<1||y<1||y>M)//坐标越界,魂穿到迷宫外了
     return 0;
  if(Map[x][y]!=1)//这个点是障碍物不能走,除非你会魔法
     return 0;
  if(vis[x][y]==1)//这个点之前走过了,好马不吃回头草
     return 0;   
  return 1;      
}

int bfs()
{
  while(q.size()>0)//队列里只要存在坐标点,就可以继续
  {
    ex1=q.front();
    q.pop();//取出队头坐标点
    if(ex1.first==x2&&ex1.second==y2)//判断是否到达终点
        return 1;
     for(int i=0;i<4;i++)//朝四个方向走
       if(check(ex1.first+dx[i],ex1.second+dy[i]))//判断某个方向能不能走通
         {
             vis[ex1.first+dx[i]][ex1.second+dy[i]]=1;//走通就表示访问过了
             q.push({ex1.first+dx[i],ex1.second+dy[i]});//放入队列中
         }
     len--;
     if(len==0)
     {
       len=q.size();
       count99++;
     }
  }
  return 0;//能执行到这里说明上面始终没到达终点,故没有路
}

int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0);
  //上面两行只是针对cin和cout来提高代码运行速度,跟题目无关,直接用c的scanf和printf就不用提速了
  cin>>N>>M;
  for(int i=1;i<=N;i++)
    for(int j=1;j<=M;j++)
    {
        cin>>Map[i][j];
        vis[i][j]=0;
    }
  cin>>x1>>yemmm>>x2>>y2;
  q.push({x1,yemmm});//把入口放入队列中
  vis[x1][yemmm]=1;//入口走通
  if(bfs())
     cout<<count99;
  else
     cout<<"-1";   
  return 0;
}

简洁版(纯代码)

#include <bits/stdc++.h>
using namespace std;
int N,M,count99=0,len=1;
int x1,yemmm,x2,y2;
pair<int,int> ex1;
int Map[110][110];
int vis[110][110];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
queue<pair<int,int> > q;

int check(int x,int y)
{
  if(x>N||x<1||y<1||y>M)
     return 0;
  if(Map[x][y]!=1)
     return 0;
  if(vis[x][y]==1)
     return 0;   
  return 1;      
}

int bfs()
{
  while(q.size()>0)
  {
    ex1=q.front();
    q.pop();
    if(ex1.first==x2&&ex1.second==y2)
        return 1;
    for(int i=0;i<4;i++)
       if(check(ex1.first+dx[i],ex1.second+dy[i]))
       {
          vis[ex1.first+dx[i]][ex1.second+dy[i]]=1;
          q.push({ex1.first+dx[i],ex1.second+dy[i]});
	   }
    len--;
    if(len==0)
    {
      len=q.size();
      count99++;
    }
  }
  return 0;
}

int main()
{
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin>>N>>M;
  for(int i=1;i<=N;i++)
    for(int j=1;j<=M;j++)
    {
	    cin>>Map[i][j];
	    vis[i][j]=0;
	}
  cin>>x1>>yemmm>>x2>>y2;
  q.push({x1,yemmm});
  vis[x1][yemmm]=1;
  if(bfs())
     cout<<count99;
  else
     cout<<"-1";   
  return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值