中山培训 2016.7.11

一天, 一个画家在森林里写生,突然爆发了山洪,他需要尽快返回住所中,那里是安
全的。
森林的地图由R行C列组成,空白区域用点“.”表示,洪水的区域用“*”表示,而
岩石用“X”表示,另画家的住所用“D”表示,画家用“S”表示。
有以下几点需要说明:
1、 每一分钟画家能向四个方向移动一格(上、下、左、右)
2、 每一分钟洪水能蔓延到四个方向的相邻格子(空白区域)
3、 洪水和画家都不能通过岩石区域
4、 画家不能通过洪水区域(同时也不行,即画家不能移到某个格子,该格子在画家达到的同时被洪水蔓延到了,这也是不允许的)
5、 洪水蔓不到画家的住所。
给你森林的地图,编写程序输出最少需要花费多长时间才能从开始的位置赶回家中。

Input

输入第一行包含两个整数R和C(R,C<=50)。
接下来R行每行包含C个字符(“.”、“*”、“X”、“D”或“S”)。地图保证只有一个“D”和一个“S”。

Output

输出画家最快安全到达住所所需的时间,如果画家不可能安全回家则输出“KAKTUS”。

Sample Input

输入1:

3 3

D.*

...

.S.



输入2:

3 3

D.*

...

..S



输入3:

3 6

D...*.

.X.X..

....S.

输出1:

3



输出2:

KAKTUS



输出3:

6

 

 

先预处理洪水没个单位时间的情况,然后BFS即可,有个特别恶心的数据,没有洪水,就WA了。

 

 

const

 dx:array[1..4] of longint=(1,0,-1,0);

 dy:array[1..4] of longint=(0,1,0,-1);

var

 a:array[0..201,-1..55,-1..55] of boolean;

 b:array[-1..55,-1..55] of boolean;

 h,k,r,c,x,y,ex,ey,num,i,j:longint;

 

procedure init;

 vark,num1:longint;

    fx,fy:array [-1..2500] of longint;

    gx,gy:array [-1..2500] of longint;

    t:string;

    ch:char;

     f:boolean;

begin

 readln(r,c);

 fori:=1 to r do

 begin

  forj:=1 to c do

   begin

    read(ch);

    ifch='D' then

     beginex:=i; ey:=j; b[i,j]:=true; end;

    ifch='S' then

     beginx:=i; y:=j; b[i,j]:=true; end;

    ifch='.' then

     b[i,j]:=true;

    ifch='X' then

    b[i,j]:=false;

    ifch='*' then

     begin

     inc(num);

     fx[num]:=i;

     fy[num]:=j;

     end;

   end;

 readln;

 end;

 

 h:=rshl 1+c shl 1;

 a[0]:=b;

 fori:=1 to h do

  begin

 

   num1:=0;

    fillchar(gx,sizeof(gx),0);

   fillchar(gy,sizeof(gy),0);

  a[i]:=a[i-1];

  f:=false;

   forj:=1 to num do

    begin

    fork:=1 to 4 do

     ifa[i,fx[j]+dx[k],fy[j]+dy[k]] and (fx[j]+dx[k]>0) and

     (fx[j]+dx[k]<=r) and (fy[j]+dy[k]>0) and (fy[j]+dy[k]<=c)

       and not ((fx[j]+dx[k]=ex) and (fy[j]+dy[k]=ey))then

     begin

      a[i,fx[j]+dx[k],fy[j]+dy[k]]:=false;

      inc(num1);

      gx[num1]:=fx[j]+dx[k];

      gy[num1]:=fy[j]+dy[k];

     end;

    end;

   num:=num1;

   fx:=gx; fy:=gy;

  end;

end;

 

 

procedure bfs;

 varhead,tail,i,nextx,nexty,t,s:longint;

    g:array [1..125000,1..3] of longint;

    flag:Array [-1..55,-1..55] of boolean;

begin

 fillchar(g,sizeof(g),0);

 flag:=b;

 tail:=1; head:=0;

 g[1,1]:=x;g[1,2]:=y; g[1,3]:=1;

repeat

 head:=head mod 2500+1;

 fori:=1 to 4 do

  begin

  nextx:=g[head,1]+dx[i];

  nexty:=g[head,2]+dy[i];

  t:=g[head,3];

 ift>h then exit;

   ifflag[nextx,nexty] and a[t,nextx,nexty] and

  (nextx>0) and (nextx<=r)

    and(nexty>0) and (nexty<=c) then

    begin

    tail:=tail mod 2500+1;

    g[tail,1]:=nextx;

    g[tail,2]:=nexty;

    g[tail,3]:=t+1;

    flag[nextx,nexty]:=false;

     if (nextx=ex) and (nexty=ey) then

      begin writeln(t); halt; end;

    end;

  end;

   ift>10 then

    inc(s);

until head=tail;

end;

 

 

begin

 init;

 bfs;

 writeln('KAKTUS');

end.

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值