题目描述
新一届智能车大赛在 JL 大学开始啦!比赛赛道可以看作是由 nn 个矩形区域拼接而成(如下图所示),每个矩形的边都平行于坐标轴,第 ii 个矩形区域的左下角和右上角坐标分别为 (x_{i,1},y_{i,1})(xi,1,yi,1) 和 (x_{i,2},y_{i,2})(xi,2,yi,2)。
题目保证:x_{i,1}<x_{i,2}=x_{i+1,1}xi,1<xi,2=xi+1,1,且 y_{i,1}< y_{i,2}yi,1<yi,2,相邻两个矩形一定有重叠在一起的边(如图中虚线所示),智能车可以通过这部分穿梭于矩形区域之间。
选手们需要在最快的时间内让自己设计的智能车从一个给定的起点 SS 点到达一个给定的终点 TT 点,且智能车不能跑出赛道。假定智能车的速度恒为 vv 且转向不消耗任何时间,你能算出最快需要多少时间完成比赛么?
输入格式
输入的第一行包含一个正整数 nn,表示组成赛道的矩形个数。
接下来 nn 行描述这些矩形,其中第 ii 行包含 44 个整数 x_{i,1}, y_{i,1}, x_{i,2}, y_{i,2}xi,1,yi,1,xi,2,yi,2,表示第 ii 个矩形左下角和右上角坐标分别为 (x_{i,1}, y_{i,1})(xi,1,yi,1) 和 (x_{i,2}, y_{i,2})(xi,2,yi,2)。
接下来一行包含两个整数 x_S, y_SxS,yS,表示起点坐标。
接下来一行包含两个整数 x_T, y_TxT,yT,表示终点坐标。
接下来一行包含一个实数 vv,表示智能车的速度。
输出格式
仅输出一个实数,至少精确到小数点后第六位,为智能车完成比赛的最快时间。
对于每个测试点,如果你的输出结果和参考结果相差不超过 10^{-6}10−6,该测试点得满分,否则不得分。
输入输出样例
输入 #1复制
2 1 1 2 2 2 0 3 4 1 1 3 0 1.0
输出 #1复制
2.41421356
说明/提示
上代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<cmath>
using namespace std;
int a[10],n,stx,sty,edx,edy,num;
int x1[2010],ydown[2010],x2[2010],y2[2010];
double v,dis[4010];
struct node{
int x;int y;
}p[5005];
void saw()
{
num=1;p[1].x=stx;p[1].y=sty;
for (int i=1;i<n;i++)
{
if (stx>x2[i]) continue;
if (x2[i]>edx) break;
a[1]=ydown[i],a[2]=y2[i],a[3]=ydown[i+1],a[4]=y2[i+1];
sort(a+1,a+1+4);
num++;
p[num].x=x2[i];
p[num].y=a[2];
num++;
p[num].x=x2[i];
p[num].y=a[3];
}
num++;
p[num].x=edx;
p[num].y=edy;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d%d%d%d",&x1[i],&ydown[i],&x2[i],&y2[i]);
scanf("%d%d%d%d",&stx,&sty,&edx,&edy);
if (stx>edx)
{
swap(stx,edx);
swap(sty,edy);
}
scanf("%lf",&v);
saw();
for (int i=2;i<=num;i++) dis[i]=1e99;
for (int i=1;i<num;i++)
{
double nox=(double)p[i].x*1.0;
double noy=(double)p[i].y*1.0;
double mmax=1e99;
double mmin=-1e99;
for (int j=i+1;j<=num;j++)
{
double len;
double nex=(double)p[j].x*1.0;
double ney=(double)p[j].y*1.0;
if (nex==nox)
{
len=abs(ney-noy);
dis[j]=min(dis[j],len+dis[i]);
continue;
}
double tmp=(ney-noy)/(nex-nox);
if ((tmp<=mmax)&&(tmp>=mmin))
{
double hh=(ney-noy)*(ney-noy)+(nex-nox)*(nex-nox);
len=sqrt(hh);
dis[j]=min(dis[j],len+dis[i]);
}
if ((j%2)==0) mmin=max(mmin,tmp);
else mmax=min(mmax,tmp);
}
}
double ans=dis[num]/v;
printf("%.10lf\n",ans);
}