POJ-3037-Skiing

本文讨论了一个滑雪者在特定地形条件下,从左上角到达右下角的最短时间问题。通过使用广度优先搜索(BFS)算法,考虑速度随高度变化的影响,实现了路径优化。
题目大意:Bessie在一个row*col的矩形区域内滑雪,起点为左上角,已知初始速度v,从a 点到 b 点时,速度变为v(a)*2^(A-B)(A,B为对应点的高度),从 a 到 b 所需的时间为 a 的速度的倒数,她可向前后左右四个方向移动,求其到右下角的最少时间。

Sample Input

1 3 3 

1 5 3 

6 3 5 

2 4 3

Sample Output

29.00

AC Code : bfs   Memory:2948K    Time:110MS

空间复杂度比较高了,貌似用优先队列会更给力。

#include <iostream> 

#include <cstdio> 

#include <cstring> 

#define Max 102 

#define Inf 0x7fffffff 

using namespace std; 

int high[Max][Max];
//double speed[Max][Max]; 

double time[Max][Max]; 

int v;
int r,c; 

int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; 

double sp(int h) 

{  double v1=v;
    int hh=high[1][1]-h; 

   if(hh>0)
        for(int i=0;i<hh;i++)
            v1*=2; 

   else
        for(int i=0;i>hh;i--)
            v1=v1/(double)2; 

   return v1;

} 

void init() 

{  scanf("%d%d%d",&v,&r,&c); 

   for(int i=1;i<=r;i++) 

   for(int j=1;j<=c;j++) 

   {  scanf("%d",&high[i][j]);
        //speed[i][j]=sp(high[i][j]); 

      time[i][j]=(double)1/sp(high[i][j]); 

    }
    //Print();

} 

int que_a[1000005];
    int que_b[1000005]; 

double spfa() 

{   int i,j;
    int a,b,a1,b1;
    int head=0,tail=0; 

    double dist[Max][Max]; 

    bool vst[Max][Max];     //是否在队列中 

    for(i=0;i<=r;i++) for(j=0;j<=c;j++) vst[i][j]=0; 

    for(i=0;i<=r;i++)
        for(j=0;j<=c;j++)
            dist[i][j]=Inf; 

    vst[1][1]=1;
    que_a[tail]=1;
    que_b[tail++]=1;

    dist[1][1]=0; 

    while(head<tail) 

   {  a=que_a[head];
        b=que_b[head++]; 

      vst[a][b]=0; 

      for(i=0;i<4;i++) 

      {   a1=a+move[i][0];
            b1=b+move[i][1]; 

          if(a1<1||b1<1||a1>r||b1>c)
            continue; 

          if(dist[a1][b1]>dist[a][b]+time[a][b]) 

          {   dist[a1][b1]=dist[a][b]+time[a][b]; 

            if(!vst[a1][b1]) 

               {
                    que_a[tail]=a1;
                    que_b[tail++]=b1;
                    vst[a1][b1]=1;
                } 

            } 

       } 

   } 

   return dist[r][c];


} 

int main() 

{
    //freopen("in.txt","r",stdin); 

    init(); 

    printf("%.2f",spfa()); 

    return 0; 

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值