//这道题就是麻烦了点,其他都很简单,细节问题。#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;#define PR 1e-8#define N 10005double edge[N][N];double dis[N];bool vis[N];struct TPoint{double x,y;TPoint(){}TPoint(double _x,double _y):x(_x),y(_y){}TPoint operator-(const TPoint p) {return TPoint(x-p.x,y-p.y);}};struct TSeg{TPoint st[2];TSeg(){}TSeg(TPoint a,TPoint b){st[0]=a,st[1]=b;}}g;struct TDoor{TSeg d[2];}door[N];int n,m;int dblcmp(double a) {return fabs(a)<PR?0:a>0?1:-1;}double cross(TPoint a,TPoint b,TPoint c){TPoint s(b-a),t(c-a);return s.x*t.y-s.y*t.x;}double dot(TPoint a,TPoint b,TPoint c){TPoint s(b-a),t(c-a);return s.x*t.x+s.y*t.y;}int betweencmp(TPoint a,TPoint b,TPoint c){return dblcmp(dot(a,b,c));}double dist(TPoint a,TPoint b){TPoint s(b-a);return sqrt(s.x*s.x+s.y*s.y);}bool segcross(TSeg a,TSeg b)//线段判交{double s1,s2,s3,s4;int d1,d2,d3,d4,l=0;d1=dblcmp(s1=cross(a.st[0],b.st[0],b.st[1]));//叉积d2=dblcmp(s2=cross(a.st[1],b.st[0],b.st[1]));d3=dblcmp(s3=cross(b.st[0],a.st[0],a.st[1]));d4=dblcmp(s4=cross(b.st[1],a.st[0],a.st[1]));if((d1^d2)==-2&&(d3^d4)==-2)//标准相交,返回交点return 1;if(d3==0&&(betweencmp(a.st[0],b.st[0],b.st[1])<=0))//a.s在线b上return 1;if(d4==0&&(betweencmp(a.st[1],b.st[0],b.st[1])<=0))//a.e在线b上return 1;if(d1==0&&(betweencmp(b.st[0],a.st[0],a.st[1])<=0))//b.s在线a上return 1;if(d2==0&&(betweencmp(b.st[1],a.st[0],a.st[1])<=0))//b.e在线a上return 1;return 0;}void getedge(){int i,j,k,i1,i2,j1,j2;bool tmp;for(i=1;i<=n+1;i++)for(j=0;j<i;j++)for(i1=0;i1<2;i1++)for(j1=0;j1<2;j1++)for(i2=0;i2<2;i2++)for(j2=0;j2<2;j2++){tmp=false;for(k=j+1;k<i;k++){g.st[0]=door[j].d[j1].st[j2];g.st[1]=door[i].d[i1].st[i2]; if(!(segcross(g,door[k].d[0]))&&!(segcross(g,door[k].d[1]))){tmp=true;break;}}if(!tmp) if(j==0) edge[j][4*i-2*i1-i2]=dist(door[j].d[j1].st[j2],door[i].d[i1].st[i2]);else edge[4*j-2*j1-j2][4*i-2*i1-i2]=dist(door[j].d[j1].st[j2],door[i].d[i1].st[i2]);}}void dijkstra(int u,int v){int i,j,k;n=4*n+1;for(i=0;i<=n;i++){dis[i]=edge[u][i];vis[i]=0;}vis[u]=1; dis[u]=0;for(i=1;i<=n;i++){int min=1e10;u=-1;for(j=0;j<=n;j++){if(!vis[j]&&dis[j]<min) {min=dis[j]; u=j;}}if(u==-1) break;vis[u]=1;for(j=0;j<=n;j++){if(!vis[j]&&dis[u]+edge[u][j]<dis[j])dis[j]=dis[u]+edge[u][j];}}printf("%.2lf\n",dis[v]);}int main(){while(scanf("%d",&n),n!=-1){int i,j,k;double x,y1,y2;door[0].d[0].st[0]=TPoint(0,5); door[0].d[0].st[1]=TPoint(0,5);door[0].d[1].st[0]=TPoint(0,5); door[0].d[1].st[1]=TPoint(0,5);for(i=1;i<=n;i++){scanf("%lf%lf%lf",&x,&y1,&y2);door[i].d[0].st[0]=TPoint(x,y1); door[i].d[0].st[1]=TPoint(x,y2);scanf("%lf%lf",&y1,&y2);door[i].d[1].st[0]=TPoint(x,y1); door[i].d[1].st[1]=TPoint(x,y2);}door[n+1].d[0].st[0]=TPoint(10,5); door[n+1].d[0].st[1]=TPoint(10,5);door[n+1].d[1].st[0]=TPoint(10,5); door[n+1].d[1].st[1]=TPoint(10,5);for(i=0;i<=4*n+4;i++) for(j=0;j<=4*n+4;j++) edge[i][j]=1e10;getedge();dijkstra(0,4*n+1);}return 0;}