滑雪(cowski.pas/c/cpp)

(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.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值