1 // 判断线段和直线相交 POJ 3304
2 // 思路:
3 // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交。
4
5 #include <cstdio>
6 #include <cstring>
7 #include <iostream>
8 #include <algorithm>
9 #include <map>
10 #include <set>
11 #include <queue>
12 #include <stdlib.h>
13 #include <cmath>
14 using namespace std;
15 typedef long long LL;
16 const LL inf = 1e18;
17 const int N = 5000;
18 const double eps = 1e-8;
19
20 int sgn(double x){
21 if(fabs(x)<eps) return 0;
22 if(x<0) return -1;
23 return 1;
24 }
25
26 struct Point{
27 double x,y;
28 Point(){}
29 Point(double _x,double _y){
30 x=_x;y=_y;
31 }
32 Point operator -(const Point &b)const{
33 return Point(x-b.x,y-b.y);
34 }
35 double operator *(const Point &b)const{
36 return x*b.x+y*b.y;
37 }
38 double operator ^(const Point &b)const{
39 return x*b.y-y*b.x;
40 }
41 };
42
43 struct Line{
44 Point s,e;
45 Line(){}
46 Line(Point _s,Point _e){
47 s=_s,e=_e;
48 }
49 };
50
51 double xmult(Point p0,Point p1,Point p2){
52 return (p1-p0)^(p2-p0);
53 }
54
55 bool Seg_inter_line(Line l1,Line l2){
56 return sgn(xmult(l2.s,l1.s,l1.e))*sgn(xmult(l2.e,l1.s,l1.e))<=0;
57 }
58
59 double dist(Point a,Point b){
60 return sqrt((a-b)*(a-b));
61 }
62 Line line[N];
63 bool work(Line l1,int n){
64 if(sgn(dist(l1.s,l1.e))==0) return false;
65 for(int i=0;i<n;i++){
66 if(Seg_inter_line(l1,line[i])==false) return false;
67 }
68 return true;
69 }
70 int main(){
71 int n,T;
72 scanf("%d",&T);
73 while(T--){
74 scanf("%d",&n);
75 double x1,y1,x2,y2;
76 for(int i=0;i<n;i++){
77 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
78 line[i]=Line(Point(x1,y1),Point(x2,y2));
79 }
80 bool flag=false;
81 for(int i=0;i<n;i++){
82 for(int j=0;j<n;j++){
83 if(work(Line(line[i].s,line[j].e),n)||work(Line(line[i].s,line[j].s),n)||work(Line(line[i].e,line[j].e),n)||work(Line(line[i].e,line[j].s),n)){
84 flag=true;
85 break;
86 }
87 }
88 if(flag) break;
89 }
90 if(flag) puts("Yes!");
91 else puts("No!");
92 }
93 return 0;
94 }