zoukankan      html  css  js  c++  java
  • POJ

    Skiing

    Bessie and the rest of Farmer John's cows are taking a trip this winter to go skiing. One day Bessie finds herself at the top left corner of an R (1 <= R <= 100) by C (1 <= C <= 100) grid of elevations E (-25 <= E <= 25). In order to join FJ and the other cows at a discow party, she must get down to the bottom right corner as quickly as she can by travelling only north, south, east, and west. 

    Bessie starts out travelling at a initial speed V (1 <= V <= 1,000,000). She has discovered a remarkable relationship between her speed and her elevation change. When Bessie moves from a location of height A to an adjacent location of eight B, her speed is multiplied by the number 2^(A-B). The time it takes Bessie to travel from a location to an adjacent location is the reciprocal of her speed when she is at the first location. 

    Find the both smallest amount of time it will take Bessie to join her cow friends. 

    Input

    * Line 1: Three space-separated integers: V, R, and C, which respectively represent Bessie's initial velocity and the number of rows and columns in the grid. 

    * Lines 2..R+1: C integers representing the elevation E of the corresponding location on the grid.

    Output

    A single number value, printed to two exactly decimal places: the minimum amount of time that Bessie can take to reach the bottom right corner of the grid.

    Sample Input

    1 3 3
    1 5 3
    6 3 5
    2 4 3

    Sample Output

    29.00

    Hint

    Bessie's best route is: 
    Start at 1,1 time 0 speed 1 
    East to 1,2 time 1 speed 1/16 
    South to 2,2 time 17 speed 1/4 
    South to 3,2 time 21 speed 1/8 
    East to 3,3 time 29 speed 1/4
     
     
    题意:以邻接矩阵形式读入各点高度,滑到某点速度为v0*2^(原点高度-某点高度),求从左上滑到右下用时。
    思路:SPFA。1.0/v即为上一点到当前点用时,扩展到右下点找出最短用时。注意到某点用时一定要提前记录,如果在扩展时现求的话会有许多重复计算,导致TLE。。(pow(,)的计算相当耗时)
    ps:SPFA O(kE),k小于等于2(已证明)E为边数,适合稀疏图(可含负边),加优化Dij O((n+m)logn)适合稠密图。在练习最短路时一直会拿这两者来比较,这次用SPFA来写,感觉和BFS相似,却也有不同之处,SPFA会用标记数组记录进入队列的点,而当点出队列时会取消标记(以后可能会再用到),进而松弛更新。
     
    #include<stdio.h>
    #include<math.h>
    #include<float.h>  //DBL_MAX头文件
    #include<queue>
    using namespace std;
    
    int a[105][105],b[105][105];
    double dis[105][105],sp[105][105];
    int t[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    int v0,r,c;
    struct Node{
        int x,y;
    }node;
    double spfa(int x,int y)
    {
        int i,j;
        queue<Node> q;
        for(i=1;i<=r;i++){
            for(j=1;j<=c;j++){
                dis[i][j]=DBL_MAX;
            }
        }
        dis[x][y]=0;
        node.x=x;
        node.y=y;
        q.push(node);
        b[x][y]=1;
        while(q.size()){
            int fx=q.front().x;
            int fy=q.front().y;
            q.pop();
            b[fx][fy]=0;
            for(i=0;i<4;i++){
                int tx=fx+t[i][0];
                int ty=fy+t[i][1];
                double t=sp[fx][fy];
                if(tx<1||ty<1||tx>r||ty>c) continue;
                if(dis[fx][fy]+t<dis[tx][ty]){
                    dis[tx][ty]=dis[fx][fy]+t;
                    if(!b[tx][ty]){
                        node.x=tx;
                        node.y=ty;
                        q.push(node);
                        b[tx][ty]=1;
                    }
                }
            }
        }
        return dis[r][c];
    }
    
    int main()
    {
        int i,j;
        scanf("%d%d%d",&v0,&r,&c);
        for(i=1;i<=r;i++){
            for(j=1;j<=c;j++){
                scanf("%d",&a[i][j]);
                sp[i][j]=1.0/(v0*pow(2.0,a[1][1]-a[i][j]));  //提前记录
            }
        }
        printf("%.2f
    ",spfa(1,1));
        return 0;
    }
  • 相关阅读:
    85个国外Ajax例子
    如何捕获方向键
    C#版对对碰[强荐]
    如何关闭移动盘的自动播放
    常用算法大全-回溯算法
    string转换成color
    常用算法大全-分而治之算法
    常用算法大全-分枝定界
    C#游戏——极品蜜蜂V1.0
    WebService传多个参数和返回多个参数的方法
  • 原文地址:https://www.cnblogs.com/yzm10/p/7270735.html
Copyright © 2011-2022 走看看