POJ 3304 Segments(计算几何:直线与线段相交)

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 }
POJ 3304

 

posted @ 2014-06-21 17:27 GLSilence 阅读(...) 评论(...) 编辑 收藏