洪水_纪中1235_bfs

Description

一天, 一个画家在森林里写生,突然爆发了山洪,他需要尽快返回住所中,那里是安
全的。
森林的地图由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.

Sample Output

输出1:

3

输出2:

KAKTUS

输出3:

6

题解:

昨天晚上的专题就是暴力搜索,于是乎就想到了搜索
记录洪水和画家的位置分别bfs两次,记录当前点的深度dep[i,j]
若同一位置,画家的深度>=洪水的深度就KAKTUS,否则输出到达房子时的深度

这里是槽点:

  • 这尼玛不止一个洪水的源头啊!!!
  • 这尼玛可能会有没有洪水的情况啊啊啊!!!

代码/pas:

type
  axis=record
    x,y,w:longint;
  end;
  state=record
    head,tail:longint;
    s:array[1..3000]of axis;
  end;
const
  dx:array[1..4]of integer=(-1,1,0,0);
  dy:array[1..4]of integer=(0,0,-1,1);
var
  n,m:longint;
  map,t,g:array[-1..100,-1..100]of longint;
  sop,fop:axis;
  a,b:state;
procedure bfs;
var
  i,x,y:longint;
begin
  t[fop.x,fop.y]:=maxlongint;
  repeat
    inc(b.head);
    for i:=1 to 4 do
    begin
      x:=b.s[b.head].x+dx[i];
      y:=b.s[b.head].y+dy[i];
      if (map[x,y]=1)and(t[x,y]=0) then
      begin
        inc(b.tail);
        b.s[b.tail].x:=x;
        b.s[b.tail].y:=y;
        b.s[b.tail].w:=b.s[b.head].w+1;
        t[x,y]:=b.s[b.tail].w;
      end;
    end;
  until b.head>=b.tail;
  fillchar(a,sizeof(a),0);
  a.tail:=1;
  a.s[1]:=sop;
  repeat;
    inc(a.head);
    if map[a.s[a.head].x,a.s[a.head].y]=2 then
    begin
      writeln(a.s[a.head].w);
      halt;
    end;
    for i:=1 to 4 do
    begin
      x:=a.s[a.head].x+dx[i];
      y:=a.s[a.head].y+dy[i];
      if (map[x,y]in[1,2])and((t[x,y]>a.s[a.head].w+1)or(t[x,y]=0))and(g[x,y]=0) then
      begin
        inc(a.tail);
        a.s[a.tail].x:=x;
        a.s[a.tail].y:=y;
        a.s[a.tail].w:=a.s[a.head].w+1;
        g[x,y]:=a.s[a.tail].w;
      end;
    end;
  until a.head>=a.tail;
end;
procedure init;
var
  i,j:longint;
  c:char;
begin
  fillchar(map,sizeof(map),0);
  readln(n,m);
  for i:=1 to n do
  begin
    for j:=1 to m do
    begin
      read(c);
      if c='X' then map[i,j]:=0;
      if c='.' then map[i,j]:=1;
      if c='D' then map[i,j]:=2;
      if c='S' then
      begin
        map[i,j]:=3;
        sop.x:=i;
        sop.y:=j;
      end;
      if c='*' then
      begin
        map[i,j]:=4;
        inc(b.tail);
        b.s[b.tail].x:=i;
        b.s[b.tail].y:=j;
      end;
    end;
    readln;
  end;
end;
begin
  init;
  bfs;
  writeln('KAKTUS');
end.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值