【USACO题库】2.4.2 Overfencing穿越栅栏(搜索)

来源:互联网 发布:p2p网络摄像机软件下载 编辑:程序博客网 时间:2024/05/09 14:10

【题目描述】

描述

农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽度W(1<=W<=38)及高度H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:

+-+-+-+-+-+|         |+-+ +-+ + +|     | | |+ +-+-+ + +| |     |  +-+ +-+-+-+

如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。

[编辑]格式

(file maze1.in)

第一行: W和H(用空格隔开)

第二行至第2 * H + 1行: 每行2 * W + 1个字符表示迷宫

[编辑]样例输入

5 3+-+-+-+-+-+|         |+-+ +-+ + +|     | | |+ +-+-+ + +| |     |  +-+ +-+-+-+

样例输入

9

【解题思路】

    可以将整个图用2*w+1,2*h+1的布尔数组表示,门口处记为一步,最后统计所有偶数行列,输出max div 2

【代码实现】

<span style="font-size:14px;">var         a:array[0..201,0..77] of char;//图         bz:array[0..201,0..77] of boolean;//标记走过没         d:array[0..15477,1..3] of longint;//广搜的数组         b:array[0..201,0..77] of longint;//存放路径         n,m,i,j,max:longint;         dx:array[1..4] of longint=(-1,0,1,0);         dy:array[1..4] of longint=(0,1,0,-1);procedure dd(x,y:longint);var         xx,yy,i,head,tail:longint;begin         fillchar(bz,sizeof(bz),true);         head:=0;         tail:=1;         d[1,1]:=x;         d[1,2]:=y;         d[1,3]:=1;         while head<tail do         begin                  inc(head);                  for i:=1 to 4 do                  begin                           xx:=d[head,1]+dx[i];                           yy:=d[head,2]+dy[i];                           if (xx>0)and(xx<=n*2+1)and(yy>0)and(yy<=m*2+1)and(a[xx,yy]=' ')and((b[xx,yy]>d[head,3]+1)or(b[xx,yy]=0)) and bz[xx,yy] then//判断条件,在图中,是否可以走,是否需要替换路径                           begin                                   inc(tail);                                   d[tail,1]:=xx;                                   d[tail,2]:=yy;//记录                                   d[tail,3]:=d[head,3]+1;//记录路径                                   b[xx,yy]:=d[tail,3];//标记最优方案                                   bz[xx,yy]:=false;//走过了                           end;                  end;         end;end;begin         readln(m,n);         fillchar(bz,sizeof(bz),true);         for i:=1 to n*2+1 do         begin                  for j:=1 to m*2+1 do                           read(a[i,j]);//输入                  readln;//一定要readln         end;         for i:=1 to n*2+1 do if a[i,1]=' ' then dd(i,1);//找迷宫两个入口         for i:=1 to n*2+1 do if a[i,m*2+1]=' ' then dd(i,m*2+1);//找迷宫2个入口         for i:=1 to m*2+1 do if a[1,i]=' ' then dd(1,i);//找迷宫2个入口         for i:=1 to m*2+1 do if a[n*2+1,i]=' ' then dd(n*2+1,i);//找迷宫2个入口         for i:=1 to n*2+1 do             if not odd(i) then                  for j:=1 to m*2+1 do                      if not odd(j) then                           if b[i,j]>max then max:=b[i,j];//寻找最大的路劲         writeln(max div 2);//div2是因为在两个格子中的空格不算end.</span>
0 0
原创粉丝点击