1. 程式人生 > >Segments

Segments

但是 algo log ret cst ive follow amp dimens

Segments

Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common.

Input

Input begins with a number T showing the number of test cases and then, T

test cases follow. Each test case begins with a line containing a positive integer n ≤ 100 showing the number of segments. After that, n lines containing four real numbers x1y1 x2 y2 follow, in which (x1, y1) and (x2, y2) are the coordinates of the two endpoints for one of the segments.

Output

For each test case, your program must output "Yes!", if a line with desired property exists and must output "No!" otherwise. You must assume that two floating point numbers a

and b are equal if |a - b| < 10-8.

Sample Input

3
2
1.0 2.0 3.0 4.0
4.0 5.0 6.0 7.0
3
0.0 0.0 0.0 1.0
0.0 1.0 0.0 2.0
1.0 1.0 2.0 1.0
3
0.0 0.0 0.0 1.0
0.0 2.0 0.0 3.0
1.0 1.0 2.0 1.0

Sample Output

Yes!
Yes!
No!

題目的意思是,求一條直線,將已知線段投影到這條直線上有一個共同交點,判斷是否存在這條直線。

這題要直接去求會很麻煩。但是想一想,將所有線段投影後,如果有共同點,則,這個點實際上是由n個點疊在一起的。如果我們把它展開了,以另一個視角觀察將會是這樣的:

技術分享

所有線段在直線ansL上都會有一個共同的投影點,A。再觀察,發現那些投影到A點的點都被直線L所經過。所以,題目就變成了,判斷是否存在一條直線,與所有線段相交。

在實際操作時,只需枚舉2n個點中任意兩個點,判斷經過這兩點的直線是否符合要求。

技術分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const double eps=1e-8;
 7 int n;
 8 struct point{double x,y;}u[105],v[105];
 9 point operator - (point P,point Q){point ret; ret.x=P.x-Q.x,ret.y=P.y-Q.y; return ret;}
10 double cross(point P,point Q){return P.x*Q.y-Q.x*P.y;}
11 bool jug(point P,point Q){
12     if (fabs(P.x-Q.x)<eps&&fabs(P.y-P.y)<eps) return 0;
13     for (int i=0; i<n; i++) if (cross(P-u[i],Q-u[i])*cross(P-v[i],Q-v[i])>eps) return 0;
14     return 1;
15 }
16 int main(){
17     int T;
18     for (scanf("%d",&T); T; T--){
19         scanf("%d",&n);
20         for(int i=0; i<n; i++) scanf("%lf%lf%lf%lf",&u[i].x,&u[i].y,&v[i].x,&v[i].y);
21         bool flag=0; if (n<3) flag=1;
22         for(int i=0; i<n-1; i++) if (!flag)
23             for(int j=i+1; j<n; j++) if (!flag)
24             if(jug(u[i],u[j])||jug(u[i],v[j])||jug(v[i],u[j])||jug(v[i],v[j])) flag=true;
25         printf("%s\n",flag?"Yes!":"No!");
26     }
27     return 0;
28 }
View Code

Segments