T2:滑雪(cowski.pas/c/cpp)

来源:互联网 发布:windows仿mac dock栏 编辑:程序博客网 时间:2024/06/05 19:53
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 Input1 3 31 5 36 3 52 4 3Sample Output29.00
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

方法:这是最短路径的问题,我们可以计算出所有的时间,在最小的时间单位(即从一次细胞移动到下一个最低高度的时间)。由于在最高高度的运动是慢251倍,有可能是在路径中的200个步骤,我们需要至少59位,所以开longlong/int64.然后就可以了,为了避免掉精度的错误,我们要加个小数输出的优化,优化如下:

double get2(double x){    double q;    long long w=floor(x*1000);    if(w%10<5)    {        w/=10;        q=w/100.0;        return q;    }    else if(w%10>5)    {        w/=10;q=(w+1)/100.0;        return q;    }    else    {        w/=10;        if((w%10)%2==0)        {            q=(w+1)/100.0;            return q;        }        else        {            q=w/100.0;            return q;        }    }}

优化方法:这个数*1000,然后取小数后两位,然后取mod判断。
代码如下:(请不要copy)

#include<cstdio>#include<cstring>#include<cmath>#define F(i,x,y) for(int i=x;i<=y;i++)using namespace std;const int maxn=100;const int w[4][2]={{1,0},{0,1},{-1,0},{0,-1}};int v,m,n;int map[maxn][maxn];double s[maxn][maxn],t[maxn][maxn];bool vis[maxn][maxn];long long power[55];struct e{int x,y;}q[maxn*maxn+20];double get2(double x){    double q;    long long w=floor(x*1000);    if(w%10<5)    {        w/=10;        q=w/100.0;        return q;    }    else if(w%10>5)    {        w/=10;q=(w+1)/100.0;        return q;    }    else    {        w/=10;        if((w%10)%2==0)        {            q=(w+1)/100.0;            return q;        }        else        {            q=w/100.0;            return q;        }    }}void SPFA(){    int head=-1,tail=0,i,tx,ty;    double tmd;    q[0].x=0,q[0].y=0;    memset(vis,false,sizeof(vis));    vis[0][0]=true;    while(head!=tail)    {        if(++head==maxn*maxn) head=0;        F(i,0,3)        {            tx=q[head].x+w[i][0];            ty=q[head].y+w[i][1];            if(tx<0 || tx==m || ty<0 ||ty==n) continue;            tmd=t[q[head].x][q[head].y]+1.0/s[q[head].x][q[head].y];            if(tmd<t[tx][ty])            {                t[tx][ty]=tmd;                if(!vis[tx][ty])                {                    if(++tail==maxn*maxn) tail=0;                    q[tail].x=tx;                    q[tail].y=ty;                    vis[tx][ty]=true;                }            }        }        vis[q[head].x][q[head].y]=false;    }}int main(){    freopen("cowski.in","r",stdin);    freopen("cowski.out","w",stdout);    scanf("%d %d %d",&v,&m,&n);    power[0]=1;    F(i,1,50) power[i]=power[i-1]<<1;    F(i,0,m-1)      F(j,0,n-1)      {        scanf("%d",&map[i][j]);        t[i][j]=power[31];      }    s[0][0]=v;    F(i,0,m-1)     F(j,0,n-1)     {         if(map[i][j]>map[0][0]) s[i][j]=v/double(power[map[i][j]-map[0][0]]);         else s[i][j]=v*power[map[0][0]-map[i][j]];     }    t[0][0]=0;    SPFA();    printf("%.2lf\n",get2(t[m-1][n-1]));    return 0;}
0 0
原创粉丝点击