回家_纪中1445_bfs+二分

来源:互联网 发布:怎么看淘宝评价五星 编辑:程序博客网 时间:2024/06/10 08:59

Description

  Alice住在森林里,森林可以看作是N*M的网格,森林里有怪兽,用‘.’表示空地,‘+’表示怪兽,‘V’表示Alice现在的位置,‘J’表示Alice的家。
  Alice可以从当前单元格向上下左右相邻单元格移动,有怪兽的地方也可以走,只不过比较危险,有怪兽的单元格对其他单元格会产生一定的危险系数,假设怪兽位置为(A,B),它对某单元格(R,C)的危险系数为:|R-A|+|C-B|,危险系数越小越危险,每个单元格的危险系数是所有怪兽对它产生的系数的最小值。
  Alice请你帮她找一条最佳路径回家,即使得路径上经过单元格的最小的危险系数最大。

Input

  输入第一行包含两个整数N和M(1<=N,M<=500),表示森林的大小。
  接下来N行每行包含M个字符:‘.’,‘+’,‘V’,‘J’。
  输入只包含一个‘V’和‘J’,而且至少有一个‘+’。

Output

  输出最佳路径中最小的危险系数。

题解

  这种题目A了才有成就感呀
  
  对于每个怪兽,我们做一次bfs求出每个点的危险系数,然后二分可能的最小危险系数值,代进bfs判断是否可行
  
   交了很多次发现原来是万恶的ansistring在捣鬼,默默吐槽然后就过了
  
   还有就是要判断起点是否大于我们二分的最小值,这点很坑
  
   优化:经过哲♂学地判断我们发现最大值不会超过50 (别问我为什么)

code

type  state=record    x,y:longint;  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:array[0..501,0..501]of longint;  f:array[0..501,0..501]of boolean;  s:array[1..251000]of state;  st,ed:state;function bfs(w:longint):boolean;var  i,x,y,head,tail:longint;begin  if map[st.x,st.y]<w then exit(false);  fillchar(s,sizeof(s),0);  fillchar(f,sizeof(f),false);  bfs:=false;  head:=0;  tail:=1;  s[1].x:=st.x;  s[1].y:=st.y;  repeat    inc(head);    if (s[head].x=ed.x)and(s[head].y=ed.y) then exit(true);    for i:=1 to 4 do    begin      x:=s[head].x+dx[i];      y:=s[head].y+dy[i];      if (not f[x,y])and(map[x,y]>=w)and(x>0)and(x<=n)and(y>0)and(y<=m) then      begin        inc(tail);        f[x,y]:=true;        s[tail].x:=x;        s[tail].y:=y;      end;    end;  until head>=tail;end;procedure main;var  l,r,mid,ans:Longint;  b:boolean;begin  l:=0;  r:=50;  ans:=0;  while l<=r do  begin    mid:=(l+r)shr 1;    b:=bfs(mid);    if b then    begin      if mid>ans then ans:=mid;      l:=mid+1;    end    else    r:=mid-1;  end;  writeln(ans);end;procedure init;var  i,j,head,tail,x,y,z:longint;  sr:ansistring;begin  fillchar(s,sizeof(s),0);  fillchar(map,sizeof(map),$7f div 2);  tail:=0;  head:=0;  readln(n,m);  for i:=1 to n do  begin    readln(sr);    for j:=1 to m do    begin      case sr[j] of        'J':        begin          ed.x:=i;          ed.y:=j;        end;        'V':        begin          st.x:=i;          st.y:=j;        end;        '+':        begin          inc(tail);          s[tail].x:=i;          s[tail].y:=j;          map[i,j]:=0;        end;      end;    end;  end;  repeat    inc(head);    for i:=1 to 4 do    begin      x:=s[head].x+dx[i];      y:=s[head].y+dy[i];      z:=map[s[head].x,s[head].y]+1;      if (map[x,y]>z)and(x>0)and(x<=n)and(y>0)and(y<=m) then      begin        inc(tail);        s[tail].x:=x;        s[tail].y:=y;        map[x,y]:=map[s[head].x,s[head].y]+1;      end;    end;  until head>=tail;end;begin  init;  main;end.
0 0
原创粉丝点击