题目描述
描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽度W(1<=W<=38)及高度H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:
如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。
输入输出格式
输入格式:
第一行: W和H(用空格隔开)
第二行至第2 H + 1行: 每行2 W + 1个字符表示迷宫
输出格式:
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
输入输出样例
输入样例#1:
5 3
输出样例#1:
9
说明
翻译来自NOCOW
USACO 2.4
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=100+5,inf=1000000000;
int w,h,f[MAXN][MAXN],ans=1;
struct node{
bool north;
bool south;
bool east;
bool west;
node(){
north=false;
south=false;
east=false;
west=false;
}
};
node room[MAXN][MAXN];
inline void read(int &x)
{
x=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
}
inline void init()
{
for(register int i=1;i<=h;++i)
{
for(register int j=1;j<=w;++j)f[i][j]=inf;
}
}
inline bool judge(int x,int y)
{
if(x<1||x>h||y<1||y>w)return false;
return true;
}
inline void search(int x,int y)
{
if(room[x][y].north)
{
int dx=x-1,dy=y;
if(judge(dx,dy)&&(f[x][y]+1<f[dx][dy]))
{
f[dx][dy]=f[x][y]+1;
search(dx,dy);
}
}
if(room[x][y].south)
{
int dx=x+1,dy=y;
if(judge(dx,dy)&&(f[x][y]+1<f[dx][dy]))
{
f[dx][dy]=f[x][y]+1;
search(dx,dy);
}
}
if(room[x][y].east)
{
int dx=x,dy=y+1;
if(judge(dx,dy)&&(f[x][y]+1<f[dx][dy]))
{
f[dx][dy]=f[x][y]+1;
search(dx,dy);
}
}
if(room[x][y].west)
{
int dx=x,dy=y-1;
if(judge(dx,dy)&&(f[x][y]+1<f[dx][dy]))
{
f[dx][dy]=f[x][y]+1;
search(dx,dy);
}
}
}
int main()
{
scanf("%d%d",&w,&h);
getchar();getchar();
char c;
for(register int i=1;i<=2*h+1;++i)
{
for(register int j=1;j<=2*w+1;++j)
{
scanf("%c",&c);
if(i%2!=0)
{
if(c==' ')
{
int a=(i+1)/2,b=j/2;
room[a][b].north=true;
room[a-1][b].south=true;
}
}
else
{
if(j%2!=0)
{
if(c==' ')
{
int a=i/2,b=(j+1)/2;
room[a][b].west=true;
room[a][b-1].east=true;
}
}
}
}
getchar();getchar();
}
init();
for(register int i=1;i<=w;++i)if(room[1][i].north)
{
f[1][i]=1;
search(1,i);
}
for(register int i=1;i<=w;++i)if(room[h][i].south)
{
f[h][i]=1;
search(h,i);
}
for(register int i=1;i<=h;++i)if(room[i][1].west)
{
f[i][1]=1;
search(i,1);
}
for(register int i=1;i<=h;++i)if(room[i][w].east)
{
f[i][w]=1;
search(i,w);
}
for(register int i=1;i<=h;++i)
{
for(register int j=1;j<=w;++j)ans=max(ans,f[i][j]);
}
cout<<ans;
return 0;
}