holiday/8.10/A-door.cpp

125 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const double inf = 1e100, EPS = 1e-6;
const int W = 20;
double l, now;
int n;
//一道墙
struct wall
{
double x, y[6], val[5];
} w[W];
// big bug:double->int
double length(double x1, double y1, double x2, double y2)
{
double x = x1 - x2, y = y1 - y2;
return sqrt(x * x + y * y);
}
double cross(double x1, double y1, double x2, double y2)
{
return x1 * y2 - x2 * y1;
}
double same(double x0, double y0, double x3, double y3, double x1, double y1, double x2, double y2)
{
double x = x3 - x0, y = y3 - y0; // y0->x0
return cross(x, y, x1 - x0, y1 - y0) * cross(x, y, x2 - x0, y2 - y0);
}
// WA double 判断正负要用
int sign(double d)
{
if (fabs(d) < EPS)
{
return 0;
}
else
return d > 0 ? 1 : -1;
}
bool ob(int li, int lj, int ri, int rj)
{
for (int i = li + 1; i < ri; i++)
{
for (int j = 0; j <= 4; j += 2)
{
// printf("(%.0lf,%.0lf)(%.0lf,%.0lf)/(%.0lf,%.0lf)(%.0lf,%.0lf):",w[i].x,w[i].y[j],w[i].x,w[i].y[j+1],w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj]);
// printf("[%.2lf/%.2lf]\n",same(w[i].x,w[i].y[j],w[i].x,w[i].y[j+1],w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj]),same(w[li].x,w[li].y[lj],w[ri].x,w[ri].y[rj],w[i].x,w[i].y[j],w[i].x,w[i].y[j+1]));
//两个都同方向才是,应该&&,错以为|| ,不是0都是真 两个小于0才是香蕉
if (sign(same(w[i].x, w[i].y[j], w[i].x, w[i].y[j + 1], w[li].x, w[li].y[lj], w[ri].x, w[ri].y[rj])) < 0 && sign(same(w[li].x, w[li].y[lj], w[ri].x, w[ri].y[rj], w[i].x, w[i].y[j], w[i].x, w[i].y[j + 1])) < 0)
{
return 0;
}
}
}
return 1;
}
void find(int ii, int jj)
{
for (int i = 0; i < ii; i++)
{
for (int j = 1; j <= 4; j++)
{
l = length(w[ii].x, w[ii].y[jj], w[i].x, w[i].y[j]);
now = w[i].val[j] + l; // i j ii,jj搞反了
if (now < w[ii].val[jj] && ob(i, j, ii, jj))
{
w[ii].val[jj] = now;
}
// printf("(%.0lf,%.0lf)(%.0lf,%.0lf):length:%.3lf,now:%.3lfval:%.3lf\n",w[ii].x,w[ii].y[jj],w[i].x,w[i].y[j],l,now,w[ii].val[jj]);
if (i == 0)
break;
}
}
}
void doit()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= 4; j++)
{
find(i, j);
if (i == n)
break;
}
}
}
int main()
{
while (1)
{
scanf("%d", &n);
if (n == -1)// 结束
return 0;
memset(&w, 0, sizeof(wall) * (n + 1));
w[0].x = 0;
w[0].y[1] = 5;
w[0].val[1] = 0;
for (int i = 1; i <= n; i++)
{
w[i].y[0] = 0;
w[i].y[5] = 10;
for (int j = 1; j <= 4; j++) //又打成i
{
w[i].val[j] = inf;
}
}
for (int i = 1; i <= n; i++)
{
scanf("%lf", &w[i].x);
// cin>>w[i].x;
for (int j = 1; j <= 4; j++) // 又是j
{
scanf("%lf", &w[i].y[j]);
// cin>>w[i].y[j];
}
}
w[++n].x = 10;
w[n].y[1] = 5;
w[n].val[1] = inf; // bug 没赋值
doit();
printf("%.2lf\n", w[n].val[1]);
}
return 0;
}