POJ 3304 Segments

蒻苣:弱弱很弱,路过的巨巨还不吝赐教!^.^...QAQ

题意:大概的意思就是,给n条线段,判断是否存在那么一条直线,能够使得每个线段的到直线上的投影至少存在一个公共点。

题解:问题可以转化为:存在一条直线,可以与所有线段相交。

证明:必要条件是所有线段投影的公共部分的垂线必定与所有线段相交。

        充分条件是如果有一条直线过所有的线段,则存在一条直线与其垂直。

然后再进一步转化:把这条直线稍微旋转,则必定会过这些线段的某两点。

最后做法就是:枚举每两个点,构成直线,判断是否存在这么两个点构成的直线 能够与所有线段相交。

注意:n==1||n==2可以特判一下,然后,重点:距离 <1E-8即可看作重点( 重点是不能算做两个点的 )

代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 #define xo 1e-8
 8 struct POINT{
 9         double x,y;
10         POINT(double a = 0, double b = 0) { x = a; y = b; }
11 };
12 struct LINESEG{
13         POINT s;
14         POINT e;
15         LINESEG( POINT a, POINT b ) { s = a; e = b; }
16         LINESEG(){}
17 };
18 LINESEG L[100+5];
19 double multiply(POINT sp, POINT ep,POINT op)
20 {
21         return ( ( sp.x - op.x )*( ep.y - op.y ) - ( sp.y - op.y )*( ep.x - op.x ) );
22 }
23 double dist( POINT p1, POINT p2 )
24 {
25         return (sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
26 }
27 bool pdd(POINT x, POINT y,int n)
28 {
29         if(dist(x,y)<xo) return 0;
30         for(int k = 0;k < n;k++)
31         {
32                 double xx =  multiply( x , L[k].e , y );
33                 double yy =  multiply( x , L[k].s , y );
34                 if(xx*yy>0) return 0;
35         }
36         return 1;
37 }
38 int main()
39 {
40         int test;
41         cin>>test;
42         while(test--)
43         {
44                 int n;
45                 cin>>n;
46                 for(int i = 0; i < n; i++ )
47                         cin>>L[i].e.x>>L[i].e.y>>L[i].s.x>>L[i].s.y;
48                 if(n==1){ printf("Yes!\n");continue; }
49                 if(n==2) { printf("Yes!\n");continue; }
50                 int pos=0;
51                 for(int i = 0;i < n; i++)
52                 {
53                         for(int j = 0;j < n;j++)
54                         {
55                                 POINT x = L[i].e;
56                                 POINT y = L[j].s;
57                                 bool pd;
58                                 pd = pdd(x,y,n);
59                                 if(pd==1){
60                                 printf("Yes!\n");pos = 1;break;}
61                                 pd = pdd(L[i].e,L[j].e,n);
62                                 if(pd==1){
63                                 printf("Yes!\n");pos = 1;break;}
64                                 pd = pdd(L[i].s,L[j].s,n);
65                                 if(pd==1){
66                                 printf("Yes!\n");pos = 1;break;}
67                         }
68                         if(pos) break;
69                 }
70                 if(!pos) printf("No!\n");
71         }
72 }
View Code

 

posted on 2015-08-21 23:00  小松song  阅读(135)  评论(0)    收藏  举报

导航