Translate:USACO/maze1

来源:互联网 发布:kmeans java实现 编辑:程序博客网 时间:2024/06/02 04:54
 

Overfencing穿越栅栏

Kolstad and Schrijvers

译 by lyl


目录

  • 1 描述
  • 2 格式
  • 3 SAMPLE INPUT
  • 4 SAMPLE OUTPUT

[编辑]描述

农夫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+2行: 每行2*W+1个字符表示迷宫

OUTPUT FORMAT:

(file maze1.out)

输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。

[编辑]SAMPLE INPUT

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

[编辑]SAMPLE OUTPUT

9
来自"http://www.nocow.cn/index.php/Translate:USACO/maze1"
 
我的做法是从每个点开始bfs,找出所有点的出迷宫的最短路,取出其中最大的一个,就是题目的答案,没有用到题目中说的两个出口。卡过。
其实正解是从两个出口处做flood fill,然后取最大路径。
const d:array[1..4,1..2] of longint=((1,0),(0,1),(-1,0),(0,-1));var s:array[0..500] of string;a:array[0..100,0..100,1..4] of boolean;dui:array[0..10000,1..3] of longint;v,fuck:array[0..101,0..101] of boolean;n,m,i,j,k,dx,dy,sum:longint;procedure find(x,y:longint);var t,w,nowx,nowy,k,min:longint;begin t:=0; w:=1; fillchar(dui,sizeof(dui),0); dui[1,1]:=x; dui[1,2]:=y; min:=maxlongint; fillchar(v,sizeof(v),0);  v[x,y]:=true; while t<w do  begin   inc(t); nowx:=dui[t,1]; nowy:=dui[t,2];   for k:=1 to 4 do    if not a[nowx,nowy,k] then    begin     dx:=nowx+d[k,1]; dy:=nowy+d[k,2];     if not v[dx,dy] then     if (dx>0) and (dy>0) and (dx<=n) and (dy<=m) then     begin      inc(w); dui[w,1]:=dx; dui[w,2]:=dy; dui[w,3]:=dui[t,3]+1;      v[dx,dy]:=true; fuck[dx,dy]:=true;     end     else      begin       if dui[t,3]+1>sum then sum:=dui[t,3]+1; exit;      end;    end;  end;  {if min>sum then sum:=min;}end;begin assign(input,'maze1.in'); assign(output,'maze1.out'); reset(input); rewrite(output); readln(m,n); for i:=1 to 2*n+1 do  readln(s[i]); for i:=1 to n do  for j:=1 to m do   for k:=1 to 4 do    begin     dx:=2*i+d[k,1]; dy:=2*j+d[k,2];     if s[dx,dy]<>' ' then a[i,j,k]:=true;    end; {for i:=1 to n do  begin  for j:=1 to m do   for k:=1 to 4 do    write(k,a[i,j,k],' ');   writeln;  end;} for i:=1 to n do  for j:=1 to m do   find(i,j); writeln(sum); close(input); close(output);end.

 
原创粉丝点击