这是我第一次使用队列(queue),第一次用BFS,第一次做最短路径的题(SP),所以来纪念一下。
题目如下:
描述
农夫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
分析:
就直接从出口处开始BFS,出口处的dis[ 出口 ]=1;然后搜索树每深入一层,该层的dis 等于上一层加一,对于两个出口分别BFS之后,在对每个位置选择距离两个出口更近的dis作为最短路径,最后输出所有点最短路径中最长的那个。
一开始处理输入数据的时候有些麻烦,尤其是找到作为出口的两个点e[0]和e[1]。
代码:
/*
ID: 15659801
LANG: C
TASK: maze1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct point
{
int x;
int y;
} point;
point queue[30000];
int end=-1,start=-1;
char map[205][85];
int w,h;
point e[2];
int cnt;
int di[4]= {-2,0,2,0};
int dj[4]= {0,2,0,-2};
int vis[205][85];
int dis[2][205][85];
int far;
int k;
void scanff(void)
{
int i,j;
char xx;
scanf("%d%d",&w,&h);
xx=getchar();
for(i=1; i<=2*h+1; i++)
{
for(j=1; j<=2*w+1; j++)
{
scanf("%c",&map[i][j]);
}
xx=getchar();
}
j=1;
for(i=2;i<=2*h;i+=2)
if(map[i][j]==' ')
{
e[cnt].x=i;
e[cnt].y=2;
cnt++;
}
j=2*w+1;
for(i=2;i<=2*h;i+=2)
if(map[i][j]==' ')
{
e[cnt].x=i;
e[cnt].y=2*w;
cnt++;
}
i=1;
for(j=2;j<=2*w;j+=2)
if(map[i][j]==' ')
{
e[cnt].x=2;
e[cnt].y=j;
cnt++;
}
i=2*h+1;
for(j=2;j<=2*w;j+=2)
if(map[i][j]==' ')
{
e[cnt].x=2*h;
e[cnt].y=j;
cnt++;
}
}
void bfs()
{
while(start!=end)
{
point now=queue[++start];
int d,nx,ny;
for(d=0; d<4; d++)
{
nx=now.x+di[d];
ny=now.y+dj[d];
point next;
next.x=nx;
next.y=ny;
if(vis[nx][ny])
continue;
if(nx==now.x&&map[nx][(ny+now.y)/2]==' '&&(ny>=2&&ny<=2*w))
{
queue[++end]=next;
vis[next.x][next.y]=1;
dis[k][next.x][next.y]=dis[k][now.x][now.y]+1;
}
if(ny==now.y&&map[(nx+now.x)/2][ny]==' '&&(nx>=2&&nx<=2*h))
{
queue[++end]=next;
vis[next.x][next.y]=1;
dis[k][next.x][next.y]=dis[k][now.x][now.y]+1;
}
}
}
}
int main ()
{
freopen ("maze1.in", "r",stdin);
freopen ("maze1.out", "w",stdout);
scanff();
for(k=0; k<2; k++)
{
memset(vis,0,sizeof(vis));
queue[++end]=e[k];
dis[k][e[k].x][e[k].y]=1;
far=1;
bfs();
}
int i,j;
for(i=2; i<=2*h; i+=2)
for(j=2; j<=2*w; j+=2)
{
if(dis[0][i][j]>dis[1][i][j])
dis[0][i][j]=dis[1][i][j];
if(dis[0][i][j]>far)
far=dis[0][i][j];
}
printf("%d\n",far);
fclose(stdin);
fclose(stdout);
exit (0);
}