做法
根据平行四边形的判定条件:
一组对边平行而相等
然后套用几何板子就能解决问题
代码
#include <bits/stdc++.h> using namespace std; const double eps=1e-8; const double PI=acos(-1.0); const double INF = 1e100; int sgn(double x){ if(fabs(x)<=eps)return 0; return x>0?1:-1; } int dcmp(const double& a, const double& b){ if(fabs(a-b)<eps) return 0; else if(a>b) return 1; return -1; } //arccos(x) double acs(double x){ if(x > 1) x = 1; else if(x < -1) x = -1; return acos(x); } //arcsin(x) double asn(double x){ if(x > 1) x = 1; else if(x < -1) x = -1; return asin(x); } struct Point{ double x,y,ang; Point(double x = 0, double y = 0):x(x),y(y){} void input(){ cin>>x>>y; } void calcangle(){ ang=atan2(y,x); } double len2() { //返回长度的平方 return x * x + y * y; } }; //计算两点距离 double distance(const Point& a, const Point& b){ return hypot(a.x-b.x,a.y-b.y); } //求两点斜率 double slope(const Point& a, const Point& b){ if(dcmp(a.x,b.x)==0) return INF; return (a.y-b.y)/(a.x-b.x); } //计算倾斜角 double gradient(const Point& a, const Point& b){ if(dcmp(a.y,b.y)==0) return 0; if(dcmp(a.x,b.x)==0) return PI/2.0; return atan(slope(a,b)); } typedef Point Vector; //判断两点是否相等 bool operator == (const Point& a, const Point& b){ return sgn(a.x-b.x)==0 && sgn(a.y-b.y)==0; } //向量点积 double operator * (const Vector& a, const Vector& b){ return a.x*b.x+a.y*b.y; } //向量叉乘,返回结果向量的有向长度 //注意叉乘的绝对值也就是两向量围成的平行四边形的面积。 double operator ^ (const Vector& a, const Vector& b){ return a.x*b.y-a.y*b.x; } //向量加法 Vector operator + (const Vector& a, const Vector& b){ return Vector(a.x+b.x,a.y+b.y); } // 向量减法 Vector operator - (const Vector& a, const Vector& b){ return Vector(a.x - b.x, a.y - b.y); } //向量数乘 Vector operator * (const Vector& a, const double& b){ return Vector(a.x*b,a.y*b); } Vector operator * (const double& a,const Vector& b){ return Vector(a*b.x,a*b.y); } Vector operator / (const Vector& a, const double& b){ return Vector(a.x/b, a.y/b); } bool operator < (const Point& a, const Point& b){ if(a.x==b.x) return a.y<b.y; return a.x<b.x; } //向量模长 double len(const Vector& x){ return sqrt(x*x); } struct Line{ Point s,e; Vector v; double ang;//直线极角 Line(Point _s,Point _e){ //两点 s = _s; e = _e; v = _e - _s; } Line(Point p,double ang){ //0<=angle<PI s=p; if(sgn(ang-PI/2)==0) e=(s+Point(0,1)); else e=(s+Point(1,tan(ang))); } Line(double a,double b,double c){ //ax+by+c=0 if(sgn(a)==0){ s=Point(0,-c/b); e=Point(1,-c/b); } else if(sgn(b)==0){ s=Point(-c/a,0); e=Point(-c/a,1); } else{ s=Point(0,-c/b); e=Point(1,(-c-a)/b); } } void input(){ s.input(); e.input(); } void clacangle(){ double ang = atan2(e.y-s.y,e.x-s.x); if(sgn(ang)<0) ang+=PI; if(sgn(ang-PI)==0) ang-=PI; } double length(){ return distance(s,e); } }; bool operator == (const Line& l,const Line& v){ //判断两条线段是否相等 return l.s == v.s && l.e == v.e; } //点和直线关系 //1 在左侧 //2 在右侧 //3 在直线上 int Relation(const Line& l,const Point& p){ int c=sgn((p-l.s)^(l.e-l.s)); if(c<0) return 1; else if(c>0) return 2; else return 3; } //两直线关系 //0 平行 //1 重合 //2 相交 int linecrossline(const Line& l,const Line& v){ if(sgn((l.e-l.s)^(v.e-v.s)) == 0) return Relation(v,l.s)==3; return 2; } void solve(){ Point a,b,c,d; a.input();b.input();c.input();d.input(); if(!linecrossline(Line(a,b),Line(c,d))){ cout<<"YES\n"; return; } if(!linecrossline(Line(a,c),Line(b,d))){ cout<<"YES\n"; return; } if(!linecrossline(Line(a,d),Line(b,c))){ cout<<"YES\n"; return; } cout<<"NO\n"; } int main(){ ios::sync_with_stdio(0);cin.tie(0); int t;cin>>t;while(t--) solve(); return 0; }