#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <vector> #include <set> #include <string> #include <math.h> #define ll long long using namespace std; const int maxn=22; const double pi=acos(-1.0); const double D_MAX=1e100; const double D_MIN=-1e100; const double eps=1e-9; int sgn(double x){ if(fabs(x) < eps)return 0; if(x >0) return 1; return -1; } int dcmp(double x, double y){ if(fabs(x - y) < eps) return 0; if(x > y) return 1;return -1;} void usehanshu(){double x;}//floor(x)向下取整函数ceil(x)向上取整函数round(x)四舍五入函数 struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {}; }; struct Segment{ Point a,b; Segment(Point x,Point y) { a=x;b=y; }; }; struct Line { Point a,b; Line(Point x,Point y) { a=x;b=y; }; }; typedef Point Vector; Vector operator + (Vector A, Vector B){ return Vector(A.x+B.x, A.y+B.y); } // 向量相加 Vector operator - (Point A, Point B){ return Vector(A.x-B.x, A.y-B.y); } // 向量生成 double operator * (Vector A, Vector B){ return A.x*B.x-A.y*B.y; } // 点积 double operator ^ (Vector A, Vector B){ return A.x*B.y-A.y*B.x; } // 叉积 double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; } // 点积 double Cross(Vector A, Vector B) { return A.x*B.y-A.y*B.x; } // 叉积 double Length(Vector A) { return sqrt(Dot(A, A));} // 向量长度 double Angle(Vector A, Vector B){ return acos(Dot(A, B)/Length(A)/Length(B));} // 角度 double Area2(Point A, Point B, Point C) { return Cross(B-A, C-A); } // 四边形面积 double dis(Point A,Point B) { return sqrt( (A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y) ); } Vector Rotate(Vector A, double rad){ return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));}//rad为弧度 且为逆时针旋转的角 Vector Normal(Vector A) {double L = Length(A);return Vector(-A.y/L, A.x/L);}//向量A左转90°的单位法向量 bool ToLeftTest(Point a, Point b, Point c){return Cross(b - a, c - b) > 0;} bool xx(Line A,Point a){if( sgn( Cross(A.a-a,A.b-a) )==0 ) return 1;return 0;} // 直线和点 void XX(Line A,Line B) // 直线和直线的情况 { Point a=A.a; Point b=A.b;Point c=B.a; Point d=B.b; double A1=b.y-a.y,B1=-(b.x-a.x),C1=b.y*a.x-b.x*a.y; double A2=d.y-c.y,B2=-(d.x-c.x),C2=d.y*c.x-d.x*c.y; double k=A1*B2-A2*B1; if(fabs(k)<eps) { if( fabs( C2*A1-C1*A2)<eps && fabs(B1*C2-C1*B2)<eps ) printf("LINE "); else printf("NONE "); } else { double x=-(B1*C2-C1*B2)*1.000000000/k; double y=(A1*C2-C1*A2)*1.00000000/k; printf("POINT %.2f %.2f ",x,y); } } // ------------------------------------------------ show time ---------------------------------------------------- //int a[maxn]; double dp[maxn][maxn]; vector<Point> vs[maxn]; vector<Segment> vd[maxn]; bool make(Line a,Segment b) { Point x=a.a; Point y=a.b; Point qq=b.a; Point pp=b.b; if( Cross(x-qq,y-qq )*Cross(x-pp,y-pp)>=0 ) return 1; return 0; } void check(int p) { for(int i=0;i<vs[p].size();i++) // qiu de hang shang de dian { dp[p][i]=D_MAX; Point X=vs[p][i]; // Point for(int j=0;j<p;j++) { for(int k=0;k<vs[j].size();k++) { Point Y=vs[j][k]; // Point int flag=1; for(int x=j+1;x<p;x++) // zhong jian hang { for(int q=0;q<vd[x].size();q++) { Segment K=vd[x][q]; if(make(Line(X,Y),K)==0) {flag=0;break;} } if(flag==0) break; } if(flag==1) { dp[p][i]=min(dp[p][i],dp[j][k]+dis(X,Y) ); } } } } } int main() { while(1) { int n; scanf("%d",&n); if(n==-1) break; vs[0].push_back(Point(0,5)); dp[0][0]=0; for(int i=1;i<=n;i++) { double x,a,b,c,d; scanf("%lf %lf %lf %lf %lf",&x,&a,&b,&c,&d); vs[i].push_back(Point(x,a)); vs[i].push_back(Point(x,b)); vs[i].push_back(Point(x,c)); vs[i].push_back(Point(x,d)); // 4 ge dian vd[i].push_back(Segment( Point(x,0.0),Point(x,a)) ); vd[i].push_back(Segment( Point(x,b),Point(x,c)) ); vd[i].push_back(Segment( Point(x,d),Point(x,10.0)) ); check(i); } vs[n+1].push_back(Point(10,5)); check(n+1); printf("%.2f ",dp[n+1][0]); for(int i=0;i<=n+1;i++){vs[i].clear(); vd[i].clear();} for(int i=0;i<=n+1;i++) for(int j=0;j<=5;j++) dp[i][j]=0; } }