POJ3037 Skiing

Skiing

题目大意:

给定一个M*N的网格,已知在每个网格中的点可以向上下左右四个方向移动一个单位,每个点都有一个高度值。 从每个点开始移动时存在一个速度值,从A点移动到B点,则此时B点的速度为"A的速度*2^(A的高度值-B的高度值)",而A点移动到B点所用的时间则是A点开始移动的速度值的倒数。 提供网格的长和宽,每个点的高度,以及在左上角的点的出发速度,问从左上角的点到右下角的点最少需要多少时间。

大致思路:

这道题,我们可以注意到其实在某一个点的速度是个固定值,因为不管怎么到达该点,这个点的速度都是1/(v*(2^(起点与该点的深度差))),求出每个点的速度后,再求最短路径就好了。

代码:

 1 #include<queue>
 2 #include<cmath>
 3 #include<cstdio>
 4 #define Max_double 11258999068426240000;
 5 #define N 110
 6 using namespace std;
 7 int d[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
 8 struct hehe{
 9     int x;
10     int y;
11 };
12 hehe p,qqq;
13 queue<hehe>q;
14 double dis[N][N];
15 bool exist[N][N];
16 int deep[N][N],v,n,m;
17 double spfa(){
18     p.x=1;
19     p.y=1;
20     dis[1][1]=0;
21     exist[1][1]=1;
22     q.push(p);
23     while(!q.empty()){
24         p=q.front();
25         q.pop();
26         exist[p.x][p.y]=0;
27         double k=1.0/(v*pow(2,1.0*deep[1][1]-deep[p.x][p.y]));
28         for(int i=0;i<4;i++){
29             int x1=p.x+d[i][0],y1=p.y+d[i][1];
30             if(x1>=1&&x1<=n&&y1>=1&&y1<=m){
31                 if(dis[x1][y1]>dis[p.x][p.y]+k){
32                     dis[x1][y1]=dis[p.x][p.y]+k;
33                     if(!exist[x1][y1]){
34                         qqq.x=x1;
35                         qqq.y=y1;
36                         q.push(qqq);
37                         exist[qqq.x][qqq.y]=1;
38                     }
39                 }
40             }
41         }    
42     }
43     return dis[n][m];
44 }
45 int main(){
46     scanf("%d%d%d",&v,&n,&m);
47     for(int i=1;i<=n;i++)
48         for(int j=1;j<=m;j++){
49             scanf("%d",&deep[i][j]);
50             dis[i][j]=Max_double;
51         }
52     printf("%.2lf",spfa());
53     return 0;
54 }
View Code

 

posted @ 2017-05-08 15:05  江屿  阅读(191)  评论(0编辑  收藏  举报