成都网站建设公司汇总深圳网站制作推广
题目描述
Description
新一届智能车大赛在JL大学开始啦!比赛赛道可以看作是由n个矩形区域拼接而成(如下图所示),每个矩形的边都平行于坐标轴,第i个矩形区域的左下角和右上角坐标分别为(xi,1,yi,1)和(xi,2,yi,2)。 题目保证:xi,1<xi,2=xi+1,1,且yi,1< yi,2,相邻两个矩形一定有重叠在一起的边(如图中虚线所示),智能车可以通过这部分穿梭于矩形区域之间。
选手们需要在最快的时间内让自己设计的智能车从一个给定的起点S点到达一个给定的终点T点,且智能车不能跑出赛道。假定智能车的速度恒为v且转向不消耗任何时间,你能算出最快需要多少时间完成比赛么?
Input
输入的第一行包含一个正整数n,表示组成赛道的矩形个数。 接下来n行描述这些矩形,其中第i行包含4个整数xi,1, yi,1, xi,2, yi,2,表示第i个矩形左下角和右上角坐标分别为(xi,1, yi,1)和(xi,2, yi,2)。 接下来一行包含两个整数xS, yS,表示起点坐标。 接下来一行包含两个整数xT, yT,表示终点坐标。 接下来一行包含一个实数v,表示智能车的速度。
Output
仅输出一个实数,至少精确到小数点后第六位,为智能车完成比赛的最快时间。
对于每个测试点,如果你的输出结果和参考结果相差不超过10^-6,该测试点得满分,否则不得分。
Sample Input
2
1 12 2
203 4
1 1
30
1.0
Sample Output
HINT
有精度误差,请不要提交
N<=2000,所输入数字为绝对值小于40000的整数
Source
day1
分析
就是求一个最短路,这条路肯定是从左到右的,我们可以用 DP 来求。
我们先预处理出矩形之间的交点,显然智能车只能经过起点、终点和这些点。
加上起点在终点左边(如果不是交换一下位置)
然后 O(n2)DP ,在 DP 过程中记录一下当前点能够向后到达的点的斜率范围就可以了。
代码
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define y1 myi
using namespace std;
#define MAXN 2000
int n,cnt,sx,sy,ex,ey,x1[MAXN+10],x2[MAXN+10],y1[MAXN+10],y2[MAXN+10];
double v,dist[MAXN*2+10];
void Read(int &x){static char c;bool f(0);while(c=getchar(),c!=EOF){if(c=='-')f=1;else if(c>='0'&&c<='9'){x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';ungetc(c,stdin);if(f)x=-x;return;}}
}
void read(){Read(n);for(int i=1;i<=n;i++)Read(x1[i]),Read(y1[i]),Read(x2[i]),Read(y2[i]);Read(sx),Read(sy),Read(ex),Read(ey);if(sx>ex)swap(sx,ex),swap(sy,ey);scanf("%lf",&v);
}
struct point{int x,y;inline point(){}inline point(int x,int y):x(x),y(y){}
}a[MAXN*2+10];
void prepare(){a[++cnt]=point(sx,sy);int t[4],i;for(i=1;i<n;i++){if(sx>x2[i])continue;if(ex<x2[i])break;t[1]=y1[i],t[2]=y2[i],t[3]=y1[i+1],t[0]=y2[i+1];sort(t,t+4);a[++cnt]=point(x2[i],t[1]);a[++cnt]=point(x2[i],t[2]);}a[++cnt]=point(ex,ey);
}
inline double sqr(double x){return x*x;
}
void solve(){int i,j;double mxk,mik,k;for(i=2;i<=cnt;i++)dist[i]=1e20;for(i=1;i<cnt;i++){mxk=1e20,mik=-1e20;for(j=i+1;j<=cnt&&mik<=mxk;j++)if(a[i].x==a[j].x)dist[j]=min(dist[j],dist[i]+abs(a[i].y-a[j].y));else{k=1.0*(a[j].y-a[i].y)/(a[j].x-a[i].x);if(mik<=k&&k<=mxk)dist[j]=min(dist[j],dist[i]+sqrt(sqr(a[j].y-a[i].y)+sqr(a[j].x-a[i].x)));if(j&1)mxk=min(mxk,k);elsemik=max(k,mik);}}
}
int main()
{read();prepare();solve();printf("%.10lf\n",dist[cnt]/v);
}