RT。。题意和思路不是很复杂。。
没有注意 n = 0 的情况 WA 了几发。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <utility>
#include <cmath>
using namespace std;
const int maxn = 20;
const double eps = 1e-4, inf = 1e10;
typedef struct point {
double x;
double y;
int num;
}point;
typedef struct v {
point start;
point end;
}v;
double multi(point p1, point p2, point p0) //used for Across
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int Across(v v1, v v2) //segmentCross,use functions: multi()
{
if(max(v1.start.x,v1.end.x) >= min(v2.start.x, v2.end.x) &&
max(v2.start.x,v2.end.x) >= min(v1.start.x, v1.end.x) &&
max(v1.start.y,v1.end.y) >= min(v2.start.y, v2.end.y) &&
multi(v2.start, v1.end, v1.start) * multi(v1.end, v2.end, v1.start) > 0 &&
multi(v1.start, v2.end, v2.start) * multi(v2.end, v1.end, v2.start) > 0)
return 1;
else
return 0;
}
point cham[maxn][6];
point p0, pe;
const int maxe = 20000, maxv = 200;
int fr[maxe], to[maxe];
double wt[maxe];
int head[maxv], next[maxe];
double sp[maxv];
int ecnt;
double dis(point a, point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
void adde(point a, point b)
{
fr[ecnt] = to[ecnt + 1] = a.num;
to[ecnt] = fr[ecnt + 1] = b.num;
wt[ecnt] = wt[ecnt + 1] = dis(a, b);
for(int i = ecnt; i < ecnt + 2; i++) {
next[i] = head[fr[i]];
head[fr[i]] = i;
}
ecnt += 2;
}
typedef pair<double, int> pii;
priority_queue <pii, vector<pii>, greater<pii> > que;
bool done[maxv];
double dijkstra()
{
sp[p0.num] = 0;
for(int i = 1; i <= pe.num; i++) sp[i] = inf;
memset(done, false, sizeof(done));
que.push(make_pair(sp[p0.num], p0.num));
while(!que.empty()) {
pii u = que.top(); que.pop();
int cur = u.second;
if(done[cur]) continue;
done[cur] = true;
for(int i = head[cur]; i != -1; i = next[i]) {
int tar = to[i];
if(sp[tar] > sp[cur] + wt[i]) {
sp[tar] = sp[cur] + wt[i];
que.push(make_pair(sp[tar], tar));
}
}
}
return sp[pe.num];
}
int main()
{
int n;
while(~scanf("%d", &n) && ~n) {
if(n == 0) {
printf("10.00\n");
continue;
}
p0.x = 0;
pe.x = 10;
p0.y = pe.y = 5;
p0.num = 0;
pe.num = n * 6;
v v0;
v0.start = p0;
v0.end = pe;
bool ok1 = true;
ecnt = 0;
memset(head, -1, sizeof(head));
for(int i = 0; i < n; i++)
for(int j = 1; j < 5; j++)
cham[i][j].num = i * 6 + j;
for(int i = 0; i < n; i++) {
scanf("%lf", &cham[i][0].x);
cham[i][0].y = 0;
for(int j = 1; j < 5; j++) {
cham[i][j].x = cham[i][0].x;
scanf("%lf", &cham[i][j].y);
bool ok = true;
v v1, v2;
v1.start = p0;
v1.end = cham[i][j];
for(int k = 0; ok && k < i; k++) {
for(int p = 0; p < 5; p += 2) {
v2.start = cham[k][p];
v2.end = cham[k][p+1];
if(fabs(v2.start.x - v2.end.x) < eps && fabs(v2.start.y - v2.end.y) < eps)
continue;
if(Across(v1, v2)) {
ok = false;
break;
}
}
}
if(ok)
adde(p0, cham[i][j]);
if(ok1 && j % 2 != 0) {
v2.start = cham[i][j-1];
v2.end = cham[i][j];
if(Across(v0, v2))
ok1 = false;
}
}
cham[i][5].x = cham[i][0].x;
cham[i][5].y = 10;
}
if(ok1)
adde(p0, pe);
for(int i = 0; i < n; i++) {
for(int it = 1; it < 5; it++) {
v v1, v2;
v1.start = cham[i][it];
for(int j = i+1; j < n; j++) {
for(int jt = 1; jt < 5; jt++) {
v1.end = cham[j][jt];
bool ok = true;
for(int k = i+1; ok && k < j; k++) {
for(int kt = 0; kt < 5; kt += 2) {
v2.start = cham[k][kt];
v2.end = cham[k][kt+1];
if(Across(v1, v2)) {
ok = false;
break;
}
}
}
if(ok)
adde(cham[i][it], cham[j][jt]);
}
}
v1.end = pe;
bool oke = true;
for(int j = i+1; oke && j < n; j++) {
for(int jt = 0; jt < 5; jt += 2) {
v2.start = cham[j][jt];
v2.end = cham[j][jt+1];
if(Across(v1, v2)) {
oke = false;
break;
}
}
}
if(oke)
adde(cham[i][it], pe);
}
}
printf("%.2lf\n", dijkstra());
}
return 0;
}