poj~1556 The Doors 计算几何+最短路
Description
Input
2
4 2 7 8 9
7 3 4.5 6 7
The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.
Output
Sample Input
1 5 4 6 7 8 2 4 2 7 8 9 7 3 4.5 6 7 -1
Sample Output
10.00 10.06
这题超级恶心,用计算几何建边 ,然后建图。
建立边的过程有点繁琐,主要是N 小
暴力建立边
主要是考虑是否会有线段相交,判断一下是否相交就好了,
通过计算几何的线段是否相交公式建边
因为这个是一排一排的
int l = (i - 1) / 4, r = (j - 1) / 4;
所以这个 l 是 i 所处的排数 r 是 j 所在的排数
点数很少 所以任意的最短路都可以跑
最后就是注意一下输出 %f
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 const double INF = 1e8; 7 const double eps = 1e-8; 8 const int maxn = 1e3 + 10; 9 double d[maxn][maxn]; 10 struct point { 11 double x, y; 12 point() {} 13 point(double x, double y): x(x), y(y) {}; 14 point operator - (const point & a) const { 15 return point(x - a.x, y - a.y); 16 } 17 double operator * (const point & a) const { 18 return x * a.x + y * a.y; 19 } 20 } p[maxn]; 21 double dist(point a, point b) { 22 return sqrt((a - b) * (a - b)); 23 } 24 double cross(point a, point b) { 25 return a.x * b.y - b.x * a.y; 26 } 27 int judge(point p1, point p2, point q1, point q2) { 28 double cros1 = cross(q1 - p1, q2 - p1); 29 double cros2 = cross(q1 - p2, q2 - p2); 30 if (fabs(cros1) < eps || fabs(cros2) < eps) return 1; 31 return cros1 * cros2 < 0 ? 1 : 0 ; 32 } 33 34 int main() { 35 int n; 36 while(scanf("%d", &n) && n != -1) { 37 p[0] = point(0, 5); 38 double x, y1, y2, y3, y4; 39 for (int i = 0 ; i < n ; i++) { 40 scanf("%lf%lf%lf%lf%lf", &x, &y1, &y2, &y3, &y4); 41 p[i * 4 + 1] = point(x, y1); 42 p[i * 4 + 2] = point(x, y2); 43 p[i * 4 + 3] = point(x, y3); 44 p[i * 4 + 4] = point(x, y4); 45 } 46 p[n * 4 + 1] = point(10, 5); 47 memset(d, 0, sizeof(d)); 48 for (int i = 0 ; i <= 4 * n + 1 ; i++) { 49 for (int j = i + 1 ; j <= 4 * n + 1 ; j++) { 50 int l = (i - 1) / 4, r = (j - 1) / 4; 51 if (i == 0) l = -1; 52 int flag = 1; 53 for (int k = l + 1 ; k < r ; k++) { 54 if (judge(p[4 * k + 1], point(p[4 * k + 1].x, 0), p[i], p[j])) { 55 flag = 0; 56 break; 57 } 58 if (judge(p[4 * k + 2], p[4 * k + 3], p[i], p[j])) { 59 flag = 0; 60 break; 61 } 62 if (judge(p[4 * k + 4], point(p[4 * k + 4].x, 10), p[i], p[j])) { 63 flag = 0; 64 break; 65 } 66 } 67 d[i][j] = d[j][i] = (flag ? dist(p[i], p[j]) : INF) ; 68 } 69 } 70 for (int k = 0 ; k <= 4 * n + 1 ; k++) 71 for (int i = 0 ; i <= 4 * n + 1 ; i++) 72 for (int j = 0 ; j <= 4 * n + 1 ; j++) 73 d[i][j] = min(d[i][j], d[i][k] + d[k][j]); 74 printf("%.2f\n", d[0][4 * n + 1]); 75 } 76 return 0; 77 }