jzoj P1028【GDOI2005】飞越原野

127 篇文章 0 订阅
45 篇文章 0 订阅

题目大意:
泰拉希尔原野是一个m*n的矩阵,它有两种地形,P表示平地,L表示湖泊,法里奥只能停留在平地上。他目前的位置在左上角(1,1)处,而目的地为右下角的(m,n)。法里奥可以向前后左右四个方向移动或者飞行,每移动一格需要1单位时间。而飞行的时间主要花费在变形上,飞行本身时间消耗很短,所以无论一次飞行多远的距离,都只需要1单位时间。飞行的途中不能变向,并且一次飞行最终必须要降落在平地上。当然,由于受到能量的限制,法里奥不能无限制的飞行,他总共最多可以飞行的距离为D。在知道了以上的信息之后,请你帮助他计算一下,他最快到达基地所需要的时间。
1<=N,M,D<=100

题解:
min[i,j,k]表示起点到点(X,Y)飞行K长度的最小时间花费。
1.枚举向四个方向行走或飞行,飞行一步时,与行走一步一样的花费,并且还浪费距离D,所以飞行一步时,采用行走的方式。
2.判断有没有出方阵/到达的地方是否为土地。
3.搜到终点点就halt退出,因为第一次找到终点的值一定是最优解。
4.如果做完广搜没有找到就输出impossible。

const
        dx:array [1..4] of longint=(1,0,-1,0);
        dy:array [1..4] of longint=(0,1,0,-1);
var
        min:array [0..101,0..101,0..101] of longint;
        v:array  [0..200001,1..4] of longint;
        r:array [0..101,0..101] of char;
        n,m,p,q,head,tail,i,j,k,ans:longint;

function check(a,b:longint):boolean;
begin
        if (a<1) or (a>n) or (b<1) or (b>m) then exit(false);
        if r[a,b]='L' then exit(false);
        exit(true);
end;

begin
        readln(n,m,p);
        for i:=1 to n do
             begin
                   for j:=1 to m do read(r[i,j]);
                   readln;
             end;
        fillchar(min,sizeof(min),$7f);
        ans:=maxlongint;
        head:=0; tail:=1;
        v[1,1]:=1; v[1,2]:=1;
        v[1,3]:=0; v[1,4]:=0;
        while head<tail do
              begin
                    inc(head);
                    for i:=1 to 4 do
                        begin
                             q:=1;
                             if p-v[head,4]>1 then q:=p-v[head,4];
                             for j:=1 to q do
                                 if  check(v[head,1]+dx[i]*j,v[head,2]+dy[i]*j)
                                     then begin
                                              if j<>1 then v[head,4]:=v[head,4]+j;
                                              if (min[v[head,1]+dx[i]*j,v[head,2]+dy[i]*j,v[head,4]]>v[head,3]+1)
                                                 then begin
                                                            inc(tail);
                                                            v[tail,1]:=v[head,1]+dx[i]*j;
                                                            v[tail,2]:=v[head,2]+dy[i]*j;
                                                            v[tail,3]:=v[head,3]+1;
                                                            v[tail,4]:=v[head,4];
                                                            min[v[tail,1],v[tail,2],v[tail,4]]:=v[tail,3];
                                                            if (v[tail,1]=n) and (v[tail,2]=m) then
                                                               begin
                                                                    writeln(v[tail,3]);
                                                                    halt;
                                                               end;
                                                      end;
                                              if j<>1 then v[head,4]:=v[head,4]-j;
                                          end;
                        end;
              end;
        if ans<>maxlongint
           then writeln(ans)
           else writeln('impossible');
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值