Overfencing穿越栅栏
Kolstad and Schrijvers
特别鸣谢lyl提供翻译!
描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽度W(1<=W<=38)及高度H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:
+-+-+-+-+-+ | | +-+ +-+ + + | | | | + +-+-+ + + | | | +-+ +-+-+-+
如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。
格式
PROGRAM NAME: maze1
INPUT FORMAT:
(file maze1.in)
第一行: W和H(用空格隔开) 第二行至第2 * H + 1行: 每行2 * W + 1个字符表示迷宫
OUTPUT FORMAT:
(file maze1.out)
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
SAMPLE INPUT
5 3 +-+-+-+-+-+ | | +-+ +-+ + + | | | | + +-+-+ + + | | | +-+ +-+-+-+
SAMPLE OUTPUT
9
分析
我们用一个数组记录每个格子四面连通情况,然后从输入文件中读入每条边(判断),维护这个数组。然后分别从两个出口做Flood fill,记录每个格子的最短距离。所有格子的最短距离的最大值为所求。
可以将整个图用2*w+1,2*h+1的布尔数组表示,门口处记为一步,最后统计所有偶数行列,输出max div 2 源码 --Lsylsy2 16:24 2007年8月2日 (CST)
还可以把两个出口分别作为起点,分别将整个地图走两遍,此时求出两次每个点到两个出口的最短距离中短的一个,再找出最短距离最长的一个点。
注意 第一组数据中 +-+ // 这行是回车,不是空格(本行有3个空格) 另注:这应该就是空格,经检验过。 +-+
小提示:使用广搜实现Flood Fill更快一点 //但是用dfs flood fill也是可以过的 时间也不算慢
补充:可将地图看为一个图,有一个额外的点表示出口,记可以到出口的一个或两个点到出口距离为1,其余的相邻联通点之间距离记为1(用bool数组即可),然后用堆优化的Dijkstra算法,只用一遍,就可求出各点到出口的最短距离,找出其中最长的即可,效率还不错。
华丽分割线
PS: 可以只做一次BFS, 把两个出口同时加入队列。
/*
ID:138_3531
LANG:C++
TASK:maze1
*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <cstring>
using namespace std;
struct Q
{
int x;
int y;
}dl[20000];
int n,w,h;
char map[300][100];
int head,tail;
int d[300][100];
int fx[4][2]={{-2,0},{0,2},{2,0},{0,-2}},fy[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
ifstream fin("maze1.in");
ofstream fout("maze1.out");
void input()
{
fin>>w>>h;
h=2*h+1;
w=2*w+1;
for(int i=1;i<=h;i++)
{
fin.get();//因为迷宫中有空格' '型字符,所以读入时不能用cin,用cin.get();
for(int j=1;j<=w;j++)
{
map[i][j]=fin.get();
//cin>>map[i][j];
if((i==1)&&(map[i][j]==' ')) {tail++;dl[tail].x=i+1;dl[tail].y=j; d[i+1][j]=1;}
if((i==h)&&(map[i][j]==' ')) {tail++;dl[tail].x=i-1;dl[tail].y=j; d[i-1][j]=1;}
if((j==1)&&(map[i][j]==' ')) {tail++;dl[tail].x=i;dl[tail].y=j+1; d[i][j+1]=1;}
if((j==w)&&(map[i][j]==' ')) {tail++;dl[tail].x=i;dl[tail].y=j-1; d[i][j-1]=1;}
}
}
}
void bfs(int head,int tail)
{
int x,y;
int p,q;
while(head!=tail)
{
head++;
x=dl[head].x;
y=dl[head].y;
for(int i=0;i<=3;i++)
{
p=x+fx[i][0];q=y+fx[i][1];
if((p>0)&&(p<h)&&(q>0)&&(q<w)&&(map[x+fy[i][0]][y+fy[i][1]]==' '))
if(d[p][q]==0)
{
tail++;
dl[tail].x=p;
dl[tail].y=q;
d[p][q]=d[x][y]+1;
}
}
}
int total=0;
for(int i=1;i<=h;i++)
for(int j=1;j<=w;j++)
total=(d[i][j]>total?d[i][j]:total);
fout<<total<<endl;
}
int main()
{
input();
bfs(head,tail);
return 0;
}