【问题描述】
FJ搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口,并且从迷宫中的任意一点都能找到一条走出迷宫的路。给定迷宫的行和列数和这个迷宫,然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的最少步数。
【输入格式】
第一行为正数m和n,表示迷宫的行数和列数,用空格隔开。迷宫用一个由数字组成的矩阵表示,一个数字表示迷宫的一个格子。每一个格子的数字告诉我们这个格子的东、西、南、北是否有栅栏存在。每个数字是由以下四个整数的某个或某几个或一个都没有加起来的。
1: 在西面有栅栏
2: 在北面有栅栏
4: 在东面有栅栏
8: 在南面有栅栏
迷宫内部的栅栏会被规定两次。比如说(1,1)南面的栅栏,亦会被标记为(2,1)北面的栅栏。
最后两行是由出口格子的行列坐标。
【输出格式】
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
【输入输出样例】
pass.in
3 5
11 2 10 2 6
3 8 14 5 5
13 3 10 12 9
3 2
3 5
pass.out
9
【输入输出样例说明】
样例输入的迷宫如图a,最糟糕的点是左下角的格子,走出迷宫需要9步,见图b。
【数据范围】
1 <= m <= 100
1 <= n <= 100
思路:将两个出口入队列进行多源BFS即可求出每个格子到任一出口的最短距离,再找到最短距离最大的那个点即可。
/*
Name: pass.cpp
Copyright: Twitter & Instagram @stevebieberjr
Author: @stevebieberjr
Date: 15/07/16 11:36
*/
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 105
using namespace std;
int a[maxn][maxn][4]; //0东 1南 2西 3北,当a[x][y][i]==1时表示(x,y)格子的i方向有墙
int n,m,x1,x2,y1,y2,vis[maxn][maxn],d[maxn][maxn];
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
struct zuobiao
{
int x,y;
}; //存储每个格子的横纵坐标
void init()
{
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int x;
scanf("%d",&x);
if(x>=8)
{
a[i][j][1]=1;
x-=8;
}
if(x>=4)
{
a[i][j][0]=1;
x-=4;
}
if(x>=2)
{
a[i][j][3]=1;
x-=2;
}
if(x>=1)
{
a[i][j][2]=1;
x-=1;
}
}
} //读入数据
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
}
void BFS()
{
queue<zuobiao>q;
q.push((zuobiao){x1,y1});
q.push((zuobiao){x2,y2}); //多源BFS,将出口的两个点坐标入队列
d[x1][y1]=1;
vis[x1][y1]=1;
d[x2][y2]=1;
vis[x2][y2]=1;
while(!q.empty())
{
zuobiao t=q.front(); q.pop();
for(int i=0;i<4;i++)
{
int nx=t.x+dx[i],ny=t.y+dy[i];
if(a[t.x][t.y][i]==1) continue; //有墙,跳过
if(nx<1 || ny<1 || nx>n || ny>m) continue; //超出棋盘范围,
if(vis[nx][ny]) continue;
vis[nx][ny]=1;
d[nx][ny]=d[t.x][t.y]+1;
q.push((zuobiao){nx,ny});
}
}
}
int main()
{
freopen("pass.in","r",stdin);
freopen("pass.out","w",stdout);
init();
int ans=0;
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
BFS(); //从出口开始BFS生成到每个点的距离
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
ans=max(ans,d[i][j]);
}
}
printf("%d\n",ans);
return 0;
}