bzoj 1644 bfs

4 篇文章 0 订阅

题意:n*m的地图,其中有障碍点不能经过,给定起点和终点,求从起点到终点最少的拐弯次数

bfs直接上...开个三维的数组times[i,j,k] 表示从k方向到(i,j)最少的转弯次数

mdzz,我果然是蒟蒻,本来以为开二维再加一个维护方向的数组,每次更新最少转弯次数的时候就更新转移方向就可以了...果然是太naive了..,可能从多个方向到某个点的转弯次数都是一样的,需要分别记录,但只开一个转移方向的数组就会只记录一个方向,那么从这个点再往外扩展就是错的了...竟然naive了一个小时....

type
        rec=record
            x,y,way:longint;
end;

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

var
        n,ssx,ssy,stx,sty,ans   :longint;
        i,j,k                   :longint;
        s                       :string;
        map                     :array[0..110,0..110] of char;
        que                     :array[0..40010] of rec;
        times                   :array[0..110,0..110,0..4] of longint;
        vis                     :array[0..110,0..110] of boolean;

procedure bfs;
var
        h,k,tl,tx,ty,curx,cury,curc:longint;
begin
   fillchar(times,sizeof(times),127);
   h:=0; tl:=0; 
   for k:=1 to 4 do
   begin
      times[ssx,ssy,k]:=0;
      inc(tl);
      que[tl].x:=ssx; que[tl].y:=ssy; que[tl].way:=k;
   end;
   //
   tl:=4;
   while (h<>tl) do
   begin
      h:=h mod 40005+1;
      curx:=que[h].x; cury:=que[h].y; curc:=que[h].way;
      for k:=1 to 4 do
      begin
         tx:=curx+walk[k,1]; ty:=cury+walk[k,2];
         if (tx>0) and (ty>0) and (tx<=n) and (ty<=n) then
           if map[tx,ty]='.' then
           begin
              if k<>curc then
              begin
                  if times[tx,ty,k]>times[curx,cury,curc]+1 then
                  begin
                     times[tx,ty,k]:=times[curx,cury,curc]+1;
                     tl:=tl mod 40005+1;
                     que[tl].x:=tx; que[tl].y:=ty; que[tl].way:=k;
                  end;
              end else
              begin
                 if times[tx,ty,k]>times[curx,cury,curc] then
                 begin
                    times[tx,ty,k]:=times[curx,cury,curc];
                    tl:=tl mod 40005+1;
                    que[tl].x:=tx; que[tl].y:=ty; que[tl].way:=k;
                 end;
              end;
           end;
      end;
   end;
end;

begin
   readln(n);
   for i:=1 to n do
   begin
      readln(s);
      for j:=1 to n do
      begin
         map[i,j]:=s[j];
         if s[j]='A' then
         begin
            ssx:=i; ssy:=j;
         end else
         if s[j]='B' then
         begin
            stx:=i; sty:=j; map[i,j]:='.';
         end;
      end;
   end;
   bfs;
   ans:=maxlongint;
   for k:=1 to 4 do if times[stx,sty,k]<ans then ans:=times[stx,sty,k];
   writeln(ans);
end.
——by Eirlys



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值