简单的判断线段是否相交,用DP求最短路。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define MAXN 1010
#define INF 1e-8
int n,bn;
double bx[MAXN],by[MAXN][3];
double ax[MAXN],ay[MAXN][10];
double f[MAXN][10];
double max(double a,double b) { if(a>b) return a; else return b; }
double min(double a,double b) { if(a<b) return a; else return b; }
void init()
{
double x,y1,y2,y3,y4;
int i,j,k,r,w;
bn = 0;
for(i=1;i<=n;i++)
{
scanf("%lf %lf %lf %lf %lf",&x,&y1,&y2,&y3,&y4);
ax[i] = x;
ay[i][1] = y1; ay[i][2] = y2;
ay[i][3] = y3; ay[i][4] = y4;
bx[++bn] = x; by[bn][1] = 0; by[bn][2] = y1;
bx[++bn] = x; by[bn][1] = y2; by[bn][2] = y3;
bx[++bn] = x; by[bn][1] = y4; by[bn][2] = 10;
}
ax[0] = 0;
ay[0][1] = ay[0][2] = ay[0][3] = ay[0][4] = 5;
n++;
ax[n] = 10;
ay[n][1] = ay[n][2] = ay[n][3] = ay[n][4] = 5;
}
double fork(double x1,double y1,double x2,double y2)
{
return x1*y2 - y1*x2;
}
double dis(double x1,double y1,double x2,double y2)
{
return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
}
double xj(double x1,double y1,double x2,double y2)
{
for(int i=1;i<=bn;i++)
{
if( fork(x1-bx[i], y1-by[i][1], 0, by[i][2]-by[i][1]) * fork(x2-bx[i], y2-by[i][1], 0, by[i][2]-by[i][1]) < -INF &&
fork(bx[i]-x1, by[i][1]-y1, x2-x1, y2-y1) * fork(bx[i]-x1, by[i][2]-y1, x2-x1, y2-y1) < -INF)
return 1;
}
return 0;
}
void solve()
{
int i,j,k,r,w;
for(i=0;i<=n;i++)
for(j=1;j<=4;j++)
f[i][j] = 20000000;
f[0][1] = f[0][2] = f[0][3] = f[0][4] = 0;
//printf("%d\n",n);
for(i=1;i<=n;i++)
for(j=0;j<i;j++)
for(r=1;r<=4;r++)
for(w=1;w<=4;w++)
if( xj(ax[i],ay[i][r],ax[j],ay[j][w]) == 0)
{
// printf("%f \n",f[i][r]);
f[i][r] = min( f[i][r] , f[j][w] + dis(ax[i],ay[i][r],ax[j],ay[j][w]) );
}
printf("%.2f\n",f[n][1]);
}
int main()
{
while(scanf("%d",&n) != EOF && n != -1)
{
init();
solve();
}
return 0;
}