zoukankan      html  css  js  c++  java
  • JZOJ 4.1 C组 飞越原野【bfs】

    Description

    勇敢的德鲁伊法里奥出色的完成了任务之后,正在迅速的向自己的基地撤退。但由于后面有着一大群追兵,所以法里奥要尽快地返回基地,否则就会被敌人捉住。
    终于,法里奥来到了最后一站:泰拉希尔原野,穿过这里就可以回到基地了。然而,敌人依然紧追不舍。不过,泰拉希尔的地理条件对法里奥十分有利,众多的湖泊随处分布。敌人需要绕道而行,但法里奥拥有变成鹰的特殊能力,使得他能轻轻松松的飞越湖面。当然,为了保证安全起见,法里奥还是决定找一条能最快回到基地的路。
    假设泰拉希尔原野是一个m*n的矩阵,它有两种地形,P表示平地,L表示湖泊,法里奥只能停留在平地上。他目前的位置在左上角(1,1)处,而目的地为右下角的(m,n)。法里奥可以向前后左右四个方向移动或者飞行,每移动一格需要1单位时间。而飞行的时间主要花费在变形上,飞行本身时间消耗很短,所以无论一次飞行多远的距离,都只需要1单位时间。飞行的途中不能变向,并且一次飞行最终必须要降落在平地上。当然,由于受到能量的限制,法里奥不能无限制的飞行,他总共最多可以飞行的距离为D。在知道了以上的信息之后,请你帮助他计算一下,他最快到达基地所需要的时间。

    Input

    第一行是3个正整数,m(1<=m<=100),n(1<=n<=100),D(1<=D<=100)。表示原野是m*n的矩阵,法里奥最多只能飞行的距离是D。
    接下来的m行每行有n个字符,相互之间没有空格。P表示当前位置为平地,L则表示湖泊。 (1,1)和(m,n)一定是平地。

    Output

    一个整数,表示法里奥到达基地需要的最短时间。如果无法到达基地,则输出impossible。

    Sample Input

    4 4 2
    PLLP
    PPLP
    PPPP
    PLLP

    Sample Output

    5


    这只是一道纯bfs
    枚举向四个方向或飞行
    用x,y求出如果进行这次飞行的到达的地方
    找到到这个地方所用的飞行距离——r
    判断有没有出方阵/到达的地方是否为土地/是否搜过。如果都符合,就入队。


    代码如下:

    uses math;
    const dx:array[1..4]of longint=(0,0,1,-1);
          dy:array[1..4]of longint=(1,-1,0,0);
          dz:array[1..4]of longint=(2,1,4,3);
    var  n,m,z,i,j,head,tail,x,y,r:longint;
         k:array[0..101,0..101]of longint;
         c:char;
         state:array[0..1000010,1..2]of longint;
         d,time,s:array[0..1000010]of longint;
         v:array[0..101,0..101,0..101]of boolean;
    begin
      readln(n,m,z);
      fillchar(v,sizeof(v),false);
      for i:=1 to n do
        begin
          for j:=1 to m do
            begin
              read(c);
              if c='P' then k[i,j]:=1 else k[i,j]:=0;
            end;
          readln;
        end;
      state[1,1]:=1;
      state[1,2]:=1;
      d[1]:=z;
      head:=0;
      tail:=1;
      repeat
        inc(head);
        for i:=1 to 4 do
          for j:=1 to d[head] do
            begin
              x:=state[head,1]+dx[i]*j;
              y:=state[head,2]+dy[i]*j;
              if (x<1)or(x>n)or(y<1)or(y>m) then break;
              if j<>1 then
                r:=max(1,d[head]-j)
              else r:=d[head];
              if (k[x,y]=0)or(v[x,y,r]=true)or(s[head]=i) then continue;
              if (x=n)and(y=m) then
                begin
                  writeln(time[head]+1);
                  exit;
                end;
              inc(tail);
              state[tail,1]:=x;
              state[tail,2]:=y;
              s[tail]:=dz[i];
              d[tail]:=r;
              time[tail]:=time[head]+1;
              v[x,y,r]:=true;
            end;
      until head>=tail;
      writeln('impossible');
    end.
  • 相关阅读:
    航班预定统计(差分数组+前缀和)
    救生艇
    Xcode 的正确打开方式——Debugging
    多次页面跳转后pop回主界面的问题
    理解Bitcode:一种中间代码
    使用AFNetWorking读取JSON出现NSCocoaErrorDomain Code=3840的解决方法
    No identities are available for signing的解决方法
    Aufree/trip-to-iOS
    Alcatraz -- 一个神奇的管理插件的Xcode插件
    GenericKeychain
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412335.html
Copyright © 2011-2022 走看看