洪水+纪中1235+bfs+水

题目大意

  一天, 一个画家在森林里写生,突然爆发了山洪,他需要尽快返回住所中,那里是安全的。

  森林的地图由R行C列组成,空白区域用点“.”表示,洪水的区域用“*”表示,而岩石用“X”表示,另画家的住所用“D”表示,画家用“S”表示。

  有以下几点需要说明:

  1、每一分钟画家能向四个方向移动一格(上、下、左、右)

  2、每一分钟洪水能蔓延到四个方向的相邻格子(空白区域)

  3、洪水和画家都不能通过岩石区域

  4、画家不能通过洪水区域(同时也不行,即画家不能移到某个格子,该格子在画家达到的同时被洪水蔓延到了,这也是不允许的)

  5、洪水蔓不到画家的住所。

  给你森林的地图,编写程序输出最少需要花费多长时间才能从开始的位置赶回家中。


分析

  水题+1;

  做题时并没有想道可以暴力bfs,又是他*3——olahiuj吱了一声,说是bfs。

  然后就轻轻松松的打了一个bfs.

  先把洪水会在哪个时间到哪一个点求出来,然后就简单了。

  注意,可能有很多初始洪水或者没有洪水(这到是我提醒olahiuj的)


代码

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

var
  b:array[0..52,0..52] of longint;
  d:array[0..52,0..52] of longint;
  x,y:array[0..7000000] of longint;
  i,j,k:longint;
  n,m:longint;
  sx,sy,ex,ey:longint;
  ans,num,max:longint;
  head,tail:longint;
  c:char;

function la(x,y,time:longint):boolean;
begin
  la:=true;
  if (x>n)or(x<1)or(y>m)or(y<1)
    then exit(false);
  if d[x,y]<=time
    then exit(false);
  if (b[x,y]<=time) or (b[x,y]=-1) or (b[x,y]=-2)
    then exit(false);
end;

procedure bfs_1;
var
  i,j,k:longint;
  x1,y1:longint;
begin
  head:=0;
  if tail=0 then exit;
  repeat
    head:=head+1;
    for i:=1 to 4 do
      begin
        x1:=x[head]+dx[i];
        y1:=y[head]+dy[i];
        if la(x1,y1,b[x[head],y[head]]+1)
          then
            begin
              tail:=tail+1;
              b[x1,y1]:=b[x[head],y[head]]+1;
              x[tail]:=x1; y[tail]:=y1;
              num:=num+1;
              if num=max then exit;
            end;
      end;
  until tail=head;
end;

procedure bfs_2;
var
  i,j,k:longint;
  x1,y1:longint;
begin
  fillchar(x,sizeof(x),0);
  fillchar(y,sizeof(y),0);
  tail:=1;
  head:=0;
  d[sx,sy]:=1;
  x[1]:=sx; y[1]:=sy;
  repeat
    head:=head+1;
    for i:=1 to 4 do
      begin
        x1:=x[head]+dx[i];
        y1:=y[head]+dy[i];
        if la(x1,y1,d[x[head],y[head]]+1)
          then
            begin
              tail:=tail+1;
              d[x1,y1]:=d[x[head],y[head]]+1;
              x[tail]:=x1; y[tail]:=y1;
            end;
        if (x1=ex) and (y1=ey)
          then
            begin
              write(d[x[head],y[head]]);
              halt;
            end;
      end;
  until tail=head;
end;

begin
  readln(n,m);
  tail:=0;
  max:=1;
  num:=0;
  fillchar(b,sizeof(b),$7f);
  fillchar(d,sizeof(d),$7f);
  for i:=1 to n do
    begin
      for j:=1 to m do
        begin
          read(c);
          if c='S'
            then
              begin
                sx:=i; sy:=j;
              end;
          if c='D'
            then
              begin
                ex:=i; ey:=j;
                b[i,j]:=-2;
              end;
          if c='*'
            then
              begin
                tail:=tail+1;
                b[i,j]:=1;
                x[tail]:=i;
                y[tail]:=j;
              end;
          if c='.'
            then
              max:=max+1;
          if c='X'
            then
              b[i,j]:=-1;
        end;
      readln;
    end;
  bfs_1;
  bfs_2;
  write('KAKTUS');
end.



posted @ 2016-07-11 12:16  一个响亮的蒟蒻  阅读(254)  评论(0编辑  收藏  举报