Segments
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
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
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