穿越栅栏

题目描述

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

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


PROGRAM NAME: maze1


 

输入

第一行: W和H(用空格隔开)
第二行至第2*H+2行:  每行2*W+1个字符表示迷宫

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

样例输出
​9

uses math;
var
        a,b,c,d,q1,q2,ans,ans1,i:longint;
        v:array[1..100000,1..4]of longint;
        r:array[-1..300,-1..100]of char;
        p:array[-1..300,-1..100]of boolean;
        s:array[1..300]of string;
const t:array[1..4,1..2]of longint=((-1,0),(0,-1),(1,0),(0,1));
begin
        readln(a,b);
        a:=2*a+1;
        b:=2*b+1;
        for c:=1 to b do
        begin
                readln(s[c]);
                for d:=1 to a do
                begin
                        r[c,d]:=s[c][d];
                end;
        end;
        fillchar(p,sizeof(p),true);
        for c:=1 to a do
        begin
                if (r[1,c]<>'-')and(r[1,c]<>'+')and(r[1,c]<>'|') then
                begin
                        inc(q2);
                        v[q2,1]:=2;
                        v[q2,2]:=c;
                        v[q2,3]:=1;
                        v[q2,4]:=q2;
                        p[2,c]:=false;
                end;
                if (r[b,c]<>'-')and(r[b,c]<>'+')and(r[b,c]<>'|') then
                begin
                        inc(q2);
                        v[q2,1]:=b-1;
                        v[q2,2]:=c;
                        v[q2,3]:=1;
                        v[q2,4]:=q2;
                        p[b-1,c]:=false;
                end;
        end;
        for c:=1 to b do
        begin
                if (r[c,1]<>'-')and(r[c,1]<>'+')and(r[c,1]<>'|') then
                begin
                        inc(q2);
                        v[q2,1]:=c;
                        v[q2,2]:=2;
                        v[q2,3]:=1;
                        v[q2,4]:=q2;
                        p[c,2]:=false;
                end;
                if (r[c,a]<>'-')and(r[c,a]<>'+')and(r[c,a]<>'|') then
                begin
                        inc(q2);
                        v[q2,1]:=c;
                        v[q2,2]:=a-1;
                        v[q2,3]:=1;
                        v[q2,4]:=q2;
                        p[c,a-1]:=false;
                end;
        end;
        while q1<q2 do
        begin
                inc(q1);
                for i:=1 to 4 do
                begin
                         if (r[(v[q1,1]+t[i,1]),(v[q1,2]+t[i,2])]<>'-')and
                        (r[(v[q1,1]+t[i,1]),(v[q1,2]+t[i,2])]<>'|')and
                        (r[(v[q1,1]+t[i,1]+t[i,1]),(v[q1,2]+t[i,2]+t[i,2])]<>'-')and
                        (r[(v[q1,1]+t[i,1]+t[i,1]),(v[q1,2]+t[i,2]+t[i,2])]<>'|')and
                        (p[(v[q1,1]+t[i,1]+t[i,1]),(v[q1,2]+t[i,2]+t[i,2])]=true)and
                        ((v[q1,1]+t[i,1]+t[i,1])in[1..b])and
                        ((v[q1,2]+t[i,2]+t[i,2])in[1..a]) then
                        begin
                                inc(q2);
                                v[q2,1]:=v[q1,1]+t[i,1]+t[i,1];
                                v[q2,2]:=v[q1,2]+t[i,2]+t[i,2];
                                v[q2,3]:=v[q1,3]+1;
                                v[q2,4]:=v[q1,4];
                                p[v[q2,1],v[q2,2]]:=false;
                                if v[q2,4]=1 then ans:=max(ans,v[q2,3]);
                                if v[q2,4]=2 then ans1:=max(ans1,v[q2,3]);
                        end;
                end;
        end;
        writeln(max(1,max(ans,ans1)));
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值