枚举两条线段的端点即可
#include<iostream> #include<stdio.h> #include<string.h> #include<string> #include<stdlib.h> #include<cmath> #include<algorithm> using namespace std; #define rd(x) scanf("%d",&x) #define rdd(x,y) scanf("%d%d",&x,&y) #define rddd(x,y,z) scanf("%d%d%d",&x,&y,&z) #define rds(s) scanf("%s",s) #define rep(i,n) for(int i=0;i<n;i++) #define LL long long const int N = 1e2+10; const int M=5e5+10; const int inf=1e9; const double esp=1e-8; const int MOD=1e9+7; int n,m; struct Point{ double x,y; Point(){ } Point(double _x,double _y){ x=_x;y=_y; } }; struct Seg{ Point s,e; Seg(){} Seg(Point _s,Point _e){ s=_s; e=_e; } }seg[N]; double cross(Point a,Point b,Point c){ return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } double dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int dcmp(double x){ if(fabs(x)<esp) return 0; return x<0?-1:1; } bool judge(Point a,Point b){ if(dcmp(dis(a,b)==0) ) return 0; for(int i=1;i<=n;i++){ int ret=dcmp(cross(a,b,seg[i].s))*dcmp(cross(a,b,seg[i].e)); if(ret>0) return false; } return true; } bool solve(){ if(n<=2) return true; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j){ if(judge(seg[i].s,seg[j].s)) return true; if(judge(seg[i].s,seg[j].e)) return true; if(judge(seg[i].e,seg[j].s)) return true; if(judge(seg[i].e,seg[j].e)) return true; } return false; } int main() { #ifndef ONLINE_JUDGE freopen("aaa","r",stdin); #endif int T; rd(T); while(T--){ rd(n); for(int i=1;i<=n;i++){ double u,v,w,z; scanf("%lf%lf%lf%lf",&u,&v,&w,&z); seg[i]=Seg(Point(u,v),Point(w,z)); } printf("%s\n",solve()?"Yes!":"No!"); } return 0; }