1. 程式人生 > >3522. 【NOIP2013模擬11.7B組】迷宮花園(maze)

3522. 【NOIP2013模擬11.7B組】迷宮花園(maze)

Description

給定一個一定存在從起點到終點的路徑的四聯通迷宮。已知Tar左右方向移動的時間為1,上下移動的時間為未知實數v。求當Tar從起點到終點的最短移動時間為已知實數L時,未知實數v是多少。

Input

輸入資料包含多個測試點。第一行為一個整數T,表示測試點的數目。
對於每一個測試點,第一行包含實數L和兩個整數R,C。R為迷宮的上下長度,C為迷宮的左右長度。
之後的R行,每行包含C個字元。其中空格表示空地,S表示起點,E表示終點,#表示圍牆。

Output

對於每一個測試點,在單獨的一行內輸出未知實數v,輸出保留5位小數。

Sample Input

2                                 
2.5 4 5                           
#####
#S  #
#  E#
#####
21 13 12
############
#S##     #E#
# ##  #  # #
#   # #  # #
### # #  # #
#   # #  # #
#  ## #  # #
##  # #  # #
### # #  # #
##  # #  # #
#  ## #    #
#     #    # 
############

Sample Output

0.50000
0.21053

Data Constraint

20%的資料,1≤ R,C ≤ 10。
100%的資料,1≤ R,C ≤ 100,0≤ v <10。

思路

先用搜索找出s到e最短路徑中走上下v和走左右的次數h,先設v為5.00000,得出時間t,因為h已經是固定的了,所以能改變的只有v,那麼如果題目的l>t,v為5+(l-t)/v,否則v為5-(l-t)/v。
保留5位小數哦。
var
  a:array[0..1000,0..1000] of char;
  b:array[0..1000,0..1000] of real;
  f:array[0..1000,0..1000] of boolean;
  x1,s1,v,h,r,c:longint;
  l:real;
procedure
main(x,y,z,s:longint);
begin if (x<=0)or(x>r)or(y<=0)or(y>c) then exit; if (z>v)and(s>h) then exit; if (s>l)and(h<>maxlongint) then exit; f[x,y]:=false; if (x=x1)and(y=s1) then begin v:=z;h:=s;end; if (f[x+1,y])and(b[x+1,y]=0)or(b[x,y]+2<b[x+1,y]) then begin
b[x+1,y]:=b[x,y]+2; main(x+1,y,z+1,s); end; if (f[x-1,y])and(b[x-1,y]=0)or(b[x,y]+2<b[x-1,y]) then begin b[x-1,y]:=b[x,y]+2; main(x-1,y,z+1,s); end; if (f[x,y-1])and(b[x,y-1]=0)or(b[x,y]+1<b[x,y-1]) then begin b[x,y-1]:=b[x,y]+1; main(x,y-1,z,s+1); end; if (f[x,y+1])and(b[x,y+1]=0)or(b[x,y]+1<b[x,y+1]) then begin b[x,y+1]:=b[x,y]+1; main(x,y+1,z,s+1); end; f[x,y]:=true; end; var i,j,k,n,x,s:longint; mid,u:real; begin assign(input,'maze.in');reset(input); assign(output,'maze.out');rewrite(output); readln(n); for i:=1 to n do begin readln(l,r,c); v:=maxlongint;h:=maxlongint; fillchar(f,sizeof(f),false); for j:=1 to r do begin for k:=1 to c do begin read(a[j,k]); if a[j,k]<>'#' then f[j,k]:=true; if a[j,k]='S' then begin x:=j;s:=k;end; if a[j,k]='E' then begin x1:=j;s1:=k;end; end; readln; end; main(x,s,0,0); mid:=0.50000; fillchar(b,sizeof(b),0); u:=v*mid+h; if u>l then mid:=mid-(u-l)/v else mid:=mid+(l-u)/v; writeln(mid:0:5); end; close(input);close(output); end.