jzoj 3522 迷宫花园

Description

给定一个一定存在从起点到终点的路径的四联通迷宫。已知Tar左右方向移动的时间为1,上下移动的时间为未知实数v。求当Tar从起点到终点的最短移动时间为已知实数L时,未知实数v是多少。

Input

输入数据包含多个测试点。第一行为一个整数T,表示测试点的数目。

对于每一个测试点,第一行包含实数L和两个整数R,C。R为迷宫的上下长度,C为迷宫的左右长度。

之后的R行,每行包含C个字符。其中空格表示空地,S表示起点,E表示终点,#表示围墙。

Output

对于每一个测试点,在单独的一行内输出未知实数v,输出保留5位小数。

Sample Input

2                                 
2.5 4 5                           
#####
#S  #
#  E#
#####
21 13 12
############
#S##     #E#
# ##  #  # #
#   # #  # #
### # #  # #
#   # #  # #
#  ## #  # #
##  # #  # #
### # #  # #
##  # #  # #
#  ## #    #
#     #    #
############

Sample Output

0.50000
0.21053

Data Constraint

20%的数据,1≤ R,C ≤ 10。
100%的数据,1≤ R,C ≤ 100,0≤ v <10。

解题思路

因为上下移动时间不知道,而这个又影响最短时间的长度,贪心不可用。
转换一下思维,若已知上下移动时间,则最短时间时间十分好求,于是二分上下移动时间v,以这个时间为已知条件跑最短路,若比最短时间还大,缩小v值,若比最短时间小,增大v值。
主要处理小数精度问题。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

#define N 110

int go[4][3]={{1,0,0},{0,1,1},{-1,0,0},{0,-1,1}};
int a[N][N];
char s[N];
int s1,s2,e1,e2;
int r,c,ti;
double l,v;
double dis[N][N];

void init()
{
    scanf("%lf%d%d\n",&l,&r,&c);
    memset(a,0,sizeof(a));
    for (int i=1;i<=r;++i)
    {
        gets(s);
        for (int j=1;j<=c;++j)
        {
            if (s[j]=='#') a[i][j]=1;
              else a[i][j]=0;
            if (s[j]=='S') {s1=i; s2=j;}
            if (s[j]=='E') {e1=i; e2=j;}
        }
    }
}

int q[N*N][2];
int head,tail;
double t[2];

double bfs(double v)
{
    t[0]=v;
    t[1]=1.00;
    for (int i=1;i<=r;++i)
      for (int j=1;j<=c;++j)
        dis[i][j]=l+1;
    memset(q,0,sizeof(q));
    head=0; tail=1;
    q[1][0]=s1;
    q[1][1]=s2;
    dis[s1][s2]=0;
    while (head<=tail)
    {
        head++;
        int i=q[head][0];
        int j=q[head][1];
        for (int k=0;k<=3;++k)
        {
            int x,y;
            x=i+go[k][0];
            y=j+go[k][1];
            if (x>r || x<1 || y>c || y<1 || a[x][y]==1) continue;
            if (dis[i][j]+t[go[k][2]]<dis[x][y]) 
            {
                dis[x][y]=dis[i][j]+t[go[k][2]];
                tail++;
                q[tail][0]=x;
                q[tail][1]=y;
            }
        }
    }
    return dis[e1][e2];
}

void find()
{
    double le,ri,mid,ans;
    le=0.00;
    ri=l;
    while (le<ri)
    {
        mid=(le+ri)/2;
        ans=bfs(mid);
        //cout<<mid<<' '<<ans<<' '<<le<<' '<<ri<<' '<<l<<endl;
        if (ans-l==0) {le=mid; ri=mid; break;}
        if (ans<l) le=mid+0.0000001;
          else ri=mid-0.0000001;
    }
    printf("%0.5lf\n",mid);
}

int main()
{
    freopen("maze.in","r",stdin);
    freopen("maze.out","w",stdout);
    scanf("%d",&ti);
    for (int p=1;p<=ti;++p)
    {
        init();
        find();
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值