(File IO): input:cowski.in output:cowski.out
Description
Bessie和其他一些人去滑雪。Bessie发现她自己站在一块R*C(1<=R,C<=100)的区域中,区域中的每一块都有一个高度值E_ij(-25<=E_ij<=25)。为了参加大家的聚会,Bessie想要尽快到达右下角。Bessie每一步只能向正东,正西,正南,正北前进一步。Bessie以初速度V(1<=V<=1,000,000)前进,她发现了一个她的速度和高度的关系。当Bessie从高度A移动到高度B时,他的速度就乘上了一个数2^(A-B)。Bessie移动一步的速度取决于她在前一格时的速度。
请找出Bessie移动所需的最小时间。
Input
第1行:3个用空格隔开的整数:V,R,C,分别表示Bessie的初速度和区域的长度和宽度
第2 - R+1行:以矩阵的形式表示该区域中各块的高度。
Output
输出一个实数(保留2位小数),表示Bessie达到目的地最少需要的时间。
Sample Input
1 3 3
1 5 3
6 3 5
2 4 3
Sample Output
29.00
Data Constraint
Hint
【样例说明】
Bessie的最佳路径是:
(1,1) 时间 0 速度 1
(1,2) 时间 1 速度 1/16
(2,2) 时间 17 速度1/4
(3,2) 时间 21 速度1/8
(3,3) 时间 29 速度 1/4
思路:这是一个明显的SPFA,稍加优化就AC了
pascal:
type
point=
record
x,y,v:longint;
end;
var
v:array[-50..50]of real;
dis:array[1..100,1..100,-50..50]of real;
w:array[1..100,1..100,-50..50]of longint;
d:array[0..1020000]of point;
pd:array[1..100,1..100,-50..50]of boolean;
a:array[1..100,1..100]of longint;
fx:array[1..4,1..2]of longint=((0,1),(0,-1),(1,0),(-1,0));
r,c,i,j,x,y,x1,y1,k,su,s1:longint;
ans:real;
procedure init;
begin
readln(su,r,c);
for i:=1 to r do
for j:=1 to c do
read(a[i,j]);
end;
procedure preparation;
begin
v[0]:=su;
for i:=1 to 50 do v[i]:=v[i-1]*2;
for i:=-1 downto -50 do v[i]:=v[i+1]/2;
end;
procedure instead;
var
x,y:longint;
begin
d[1]:=d[k];
dec(k);
x:=1;
while x*2<=k do
begin
if (x*2=k)or
(dis[d[x*2].x,d[x*2].y,d[x*2].v]<dis[d[x*2+1].x,d[x*2+1].y,d[x*2+1].v])then
y:=x*2
else y:=x*2+1;
if dis[d[y].x,d[y].y,d[y].v]>dis[d[x].x,d[x].y,d[x].v] then break;
d[0]:=d[x];
d[x]:=d[y];
d[y]:=d[0];
w[d[x].x,d[x].y,d[x].v]:=x;
w[d[y].x,d[y].y,d[y].v]:=y;
x:=y;
end;
end;
procedure up(x:longint);
var
y:longint;
begin
while x>1 do
begin
y:=x>>1;
if dis[d[x].x,d[x].y,d[x].v]<dis[d[y].x,d[y].y,d[y].v] then
begin
d[0]:=d[x];
d[x]:=d[y];
d[y]:=d[0];
w[d[x].x,d[x].y,d[x].v]:=x;
w[d[y].x,d[y].y,d[y].v]:=y;
x:=y;
end
else break;
end;
end;
procedure dij;
begin
k:=1;
d[1].x:=1;
d[1].y:=1;
d[1].v:=0;
fillchar(dis,sizeof(dis),$7f);
fillchar(pd,sizeof(pd),false);
pd[1,1,0]:=true;
ans:=dis[1,1,0];
dis[1,1,0]:=0;
w[1,1,0]:=1;
while k>0 do
begin
x:=d[1].x;
y:=d[1].y;
su:=d[1].v;
instead;
for i:=1 to 4 do
begin
x1:=x+fx[i,1];
y1:=y+fx[i,2];
if(x1=0)or(x1>r)or(y1=0)or(y1>c)then continue;
s1:=su+a[x,y]-a[x1,y1];
if dis[x,y,su]+1/v[su]<dis[x1,y1,s1] then
begin
dis[x1,y1,s1]:=dis[x,y,su]+1/v[su];
if not pd[x1,y1,s1] then
begin
pd[x1,y1,s1]:=true;
inc(k);
d[k].x:=x1;
d[k].y:=y1;
d[k].v:=s1;
w[x1,y1,s1]:=k;
end;
up(w[x1,y1,s1]);
end;
end;
pd[x,y,su]:=false;
end;
end;
procedure print;
begin
for i:=-50 to 50 do
if ans>dis[r,c,i] then
begin
ans:=dis[r,c,i];
end;
writeln(abs(ans-0.00000000005):0:2);
end;
begin
assign(input,'cowski.in');reset(input);
assign(output,'cowski.out');rewrite(output);
init;
preparation;
dij;
print;
close(input);
close(output);
end.