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; }
来源:https://www.cnblogs.com/AbandonZHANG/archive/2012/06/19/2598280.html