POJ-3037-Skiing

题目大意: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; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值