【USACO题库】2.4.2 Overfencing穿越栅栏

题目描述


农夫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


这道题其实比较简单,就是搜索罢了,只不过这里需要注意的是,判断当前这一格是否能走,应该判断a[x*2+dx[i],y*2+dy[i]],x,y表示当前走到哪一格,以n,m为准。但是如果直接判断a[x,y]的话,根据输入的数据看出是不行的。

bfs(1ms):

const
        dx:array[1..4] of Longint=(-1,0,1,0);
        dy:array[1..4] of Longint=(0,1,0,-1);
var
        f:array[1..100,1..38] of Longint;
        a:array[1..201,1..77] of char;
        n,m,i,j,ans:Longint;
procedure bfs(x,y:Longint);
var
        d:array[1..3800] of record
                x,y,tot:Longint;
        end;
        head,tail,i,xx,yy:Longint;
begin
        head:=0;
        tail:=1;

        d[1].x:=x;
        d[1].y:=y;
        d[1].tot:=1;

        f[x,y]:=1;
        while head<tail do
        begin
            inc(head);
            for i:=1 to 4 do
            begin
                xx:=d[head].x+dx[i]; yy:=d[head].y+dy[i];
                if (xx>0) and (yy>0) and (xx<=n) and (yy<=m) and (f[xx,yy]>d[head].tot+1) and (a[d[head].x*2+dx[i],d[head].y*2+dy[i]]=' ') then
                begin
                        inc(tail);
                        d[tail].x:=xx;
                        d[tail].y:=yy;
                        d[tail].tot:=d[head].tot+1;
                        f[d[tail].x,d[tail].y]:=d[tail].tot;
                end;
            end;
        end;
end;

begin
        readln(m,n);
        for i:=1 to n*2+1 do
        begin
                for j:=1 to m*2+1 do
                        read(a[i,j]);
                readln;
        end;

        fillchar(f,sizeof(f),5);
        for i:=1 to n do
        begin
                if a[i*2,1]=' ' then bfs(i,1);
                if a[i*2,2*m+1]=' ' then bfs(i,m);
        end;
        for i:=1 to m do
        begin
                if a[1,i*2]=' ' then bfs(1,i);
                if a[2*n+1,i*2]=' ' then bfs(n,i);
        end;

        ans:=-maxLongint;
        for i:=1 to n do
                for j:=1 to m do
                        if f[i,j]>ans then ans:=f[i,j];
        writeln(ans);
end.

dfs(26ms):

var
        f:array[1..100,1..38] of Longint;
        a:array[1..201,1..77] of char;
        n,m,i,j,ans:Longint;
procedure dfs(x,y,tot:Longint);
var
        k,xx,yy:Longint;
begin
        if f[x,y]>tot then
                f[x,y]:=tot
        else exit;

        if (a[x*2-1,y*2]=' ') and (x>1) then dfs(x-1,y,tot+1);
        if (a[x*2+1,y*2]=' ') and (x<n) then dfs(x+1,y,tot+1);
        if (a[x*2,y*2-1]=' ') and (y>1) then dfs(x,y-1,tot+1);
        if (a[x*2,y*2+1]=' ') and (y<m) then dfs(x,y+1,tot+1);
end;
begin
        readln(m,n);
        for i:=1 to n*2+1 do
        begin
                for j:=1 to m*2+1 do
                        read(a[i,j]);
                readln;
        end;

        fillchar(f,sizeof(f),5);

        for i:=1 to n do
        begin
                if a[i*2,1]=' ' then dfs(i,1,1);
                if a[i*2,2*m+1]=' ' then dfs(i,m,1);
        end;
        for i:=1 to m do
        begin
                if a[1,i*2]=' ' then dfs(1,i,1);
                if a[2*n+1,i*2]=' ' then dfs(n,i,1);
        end;

        ans:=-maxLongint;
        for i:=1 to n do
                for j:=1 to m do
                        if f[i,j]>ans then ans:=f[i,j];
        writeln(ans);
end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值