{BFS水过。。。}
program maze1;
const
dx:array [1..4] of -1..1=(-1,0,1,0);
dy:array [1..4] of -1..1=(0,1,0,-1);
type atp=record
x,y,depth:longint;
end;
var
dep1,dep2,dep:array [0..201,0..201] of longint;//dep1[x,y]记录从第一个门到(x,y)点的最短距离,dep2[x,y]记录从第二个门到(x,y)点的最短距离,dep[x,y]记录dep1和dep2的最小值。
b:array [0..201,0..201] of boolean;
que:array [0..1000000] of atp;//que为BFS队列。
w,h,sx1,sy1,sx2,sy2,head,tail:longint;//sx1,sy1分别代表第一个门的横纵坐标,同理sx2,sy2代表第二个门的横纵坐标。
a:array [0..201,0..201] of 0..2;
procedure init;
var
i,j:longint;
t:char;
begin
//我是采用抽象为点的做法做的,不管当前位置是加号或是减号还是竖线全为1,其它除了门之外能走的地方全是0,门是2。
readln(w,h);
for i:=2*h+1 downto 1 do
begin
for j:=1 to 2*w+1 do
begin
read(t);
case t of
'+':a[j,i]:=1;
'-':a[j,i]:=1;
'|':a[j,i]:=1;
' ':begin
if (i=2*h+1) or (j=2*w+1) or (j=1) or (i=1) then
begin
a[j,i]:=2;
if sx1=0 then
begin
sx1:=j;
sy1:=i;
end
else
begin
sx2:=j;
sy2:=i;
end;
end
else a[j,i]:=0;
end;
end;
end;
readln;
end;
end;
function minest(x,y:longint):longint;
begin
if x>y then exit(y) else exit(x);
end;
procedure bfs;
var
max,tx,ty,i,j:longint;
begin
fillchar(que,sizeof(que),0);
head:=0;
tail:=1;
fillchar(b,sizeof(b),false);
b[sx1,sy1]:=true;
que[1].x:=sx1;
que[1].y:=sy1;
que[1].depth:=1;
while head<=tail do
begin
inc(head);
for i:=1 to 4 do
begin
tx:=que[head].x+dx[i];
ty:=que[head].y+dy[i];
if (tx<=2*w+1) and (tx>=1) and (ty>=1) and (ty<=2*h+1) and (not b[tx,ty]) and (a[tx,ty]=0) then
begin
inc(tail);
b[tx,ty]:=true;
que[tail].x:=tx;
que[tail].y:=ty;
que[tail].depth:=que[head].depth+1;
dep1[tx,ty]:=que[tail].depth;//每次都记录一下大门到当前位置的距离
end;
end;
end;
fillchar(que,sizeof(que),0);
head:=0;
tail:=1;
fillchar(b,sizeof(b),false);
b[sx2,sy2]:=true;
que[1].x:=sx2;
que[1].y:=sy2;
que[1].depth:=1;
while head<=tail do
begin
inc(head);
for i:=1 to 4 do
begin
tx:=que[head].x+dx[i];
ty:=que[head].y+dy[i];
if (tx<=2*w+1) and (tx>=1) and (ty>=1) and (ty<=2*h+1) and (not b[tx,ty]) and (a[tx,ty]=0) then
begin
inc(tail);
b[tx,ty]:=true;
que[tail].x:=tx;
que[tail].y:=ty;
que[tail].depth:=que[head].depth+1;
dep2[tx,ty]:=que[tail].depth;//同上。
end;
end;
end;
max:=-maxlongint;
for i:=2*h+1 downto 1 do
begin
for j:=1 to 2*w+1 do
begin
if (a[j,i]=0) and (i mod 2=0) and (j mod 2=0) then
begin
dep[j,i]:=minest(dep1[j,i],dep2[j,i]);//就卡在这了,题意没理解清,先求当前位置是走第一个大门近还是走第二个大门近,先刷一遍。
if dep[j,i]>max then max:=dep[j,i];//再在所有的位置中找一个最大值即为所求。
end;
end;
end;
writeln(max shr 1);
end;
begin
assign(input,'maze1.in'); reset(input);
assign(output,'maze1.out'); rewrite(output);
init;
bfs;
close(input); close(output);
end.

419

被折叠的 条评论
为什么被折叠?



