POJ 3304 Segments(计算几何:直线与线段相交)
大意:给你一些线段,找出一条直线能够穿过所有的线段,相交包括端点。
思路:遍历所有的端点,取两个点形成直线,判断直线是否与所有线段相交,如果存在这样的直线,输出Yes,但是注意去重。
1 struct Point 2 { 3 double x, y; 4 } P[210]; 5 struct Line 6 { 7 Point a, b; 8 } L[110]; 9 10 double xmult(Point p1, Point p2, Point p) 11 { 12 return (p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x); 13 } 14 15 bool segLineInter(Line seg, Line line) 16 { 17 double d1, d2; 18 d1 = xmult(seg.a, line.a, line.b); 19 d2 = xmult(seg.b, line.a, line.b); 20 if((d1>eps && d2 < -eps) || (d1 < -eps && d2 > eps)) 21 return true; 22 if(fabs(d1) < eps || fabs(d2) < eps) 23 return true; 24 return false; 25 } 26 27 int T; 28 int n; 29 30 void Solve() 31 { 32 Line l1, l2; 33 scanf("%d", &T); 34 while(T--) 35 { 36 scanf("%d", &n); 37 int t = 0; 38 for(int i = 0; i < n; ++i) 39 { 40 scanf("%lf%lf%lf%lf", &L[i].a.x, &L[i].a.y, &L[i].b.x, &L[i].b.y); 41 P[t++] = L[i].a; 42 P[t++] = L[i].b; 43 } 44 bool ans = false; 45 for(int i = 0; !ans && i < t; ++i) 46 { 47 for(int j = i+1; j < t; ++j) 48 { 49 bool flag = true; 50 if(fabs(P[i].x-P[j].x) < eps && fabs(P[i].y-P[j].y) < eps) continue; 51 for(int k = 0; k < n; ++k) 52 { 53 if(segLineInter(L[k], (Line){P[i], P[j]}) == false) 54 { 55 flag = false; 56 break; 57 } 58 } 59 if(flag == true) 60 { 61 ans = true; 62 break; 63 } 64 } 65 } 66 printf("%s!\n", ans?"Yes":"No"); 67 } 68 }