题意
分析
就判断两个点集的凸包相离即可。
需要满足如下两个条件:
- 两凸包上任意两条线段不相交。
- 两凸包上任意一点不在另一凸包的内部。
时间复杂度\(O(T n m)\)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<set> #include<map> #include<queue> #include<stack> #include<algorithm> #include<bitset> #include<cassert> #include<ctime> #include<cstring> #define rg register #define il inline #define co const template<class T>il T read() { rg T data=0; rg int w=1; rg char ch=getchar(); while(!isdigit(ch)) { if(ch=='-') w=-1; ch=getchar(); } while(isdigit(ch)) { data=data*10+ch-'0'; ch=getchar(); } return data*w; } template<class T>T read(T&x) { return x=read<T>(); } using namespace std; typedef long long ll; co double eps=1e-10; double dcmp(double x) { return fabs(x)<eps?0:(x<0?-1:1); } struct Point { double x,y; Point(double x=0,double y=0) :x(x),y(y){} bool operator<(co Point&rhs)co { return x<rhs.x||(x==rhs.x&&y<rhs.y); } bool operator==(co Point&rhs)co { return x==rhs.x&&y==rhs.y; } }; typedef Point Vector; Vector operator-(co Vector&A,co Vector&B) { return Vector(A.x-B.x,A.y-B.y); } double Dot(co Vector&A,co Vector&B) { return A.x*B.x+A.y*B.y; } double Cross(co Vector&A,co Vector&B) { return A.x*B.y-A.y*B.x; } bool SegmentProperIntersection(co Point&a1,co Point&a2,co Point&b1,co Point&b2) { double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1), c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1); return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0; } bool OnSegment(co Point&p,co Point&a1,co Point&a2) { return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0; } vector<Point>ConvexHull(vector<Point>p) { sort(p.begin(),p.end()); p.erase(unique(p.begin(),p.end()),p.end()); int n=p.size(); int m=0; vector<Point>ch(n+1); for(int i=0;i<n;++i) { while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) --m; ch[m++]=p[i]; } int k=m; for(int i=n-2;i>=0;--i) { while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) --m; ch[m++]=p[i]; } if(n>1) m--; ch.resize(m); return ch; } int PointInPolygon(co Point&p,co vector<Point>&poly) { int wn=0; int n=poly.size(); for(int i=0;i<n;++i) { co Point&p1=poly[i]; co Point&p2=poly[(i+1)%n]; if(p1==p||p2==p||OnSegment(p,p1,p2)) return -1; int k=dcmp(Cross(p2-p1,p-p1)); int d1=dcmp(p1.y-p.y); int d2=dcmp(p2.y-p.y); if(k>0&&d1<=0&&d2>0) ++wn; if(k<0&&d2<=0&&d1>0) --wn; } if(wn!=0) return 1; return 0; } bool ConvexPolygonDisjoint(co vector<Point>ch1,co vector<Point>&ch2) { int c1=ch1.size(); int c2=ch2.size(); for(int i=0;i<c1;++i) if(PointInPolygon(ch1[i],ch2)!=0) return 0; for(int i=0;i<c2;++i) if(PointInPolygon(ch2[i],ch1)!=0) return 0; for(int i=0;i<c1;++i) for(int j=0;j<c2;++j) if(SegmentProperIntersection(ch1[i],ch1[(i+1)%c1],ch2[j],ch2[(j+1)%c2])) return 0; return 1; } int main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); int n,m; while(read(n)|read(m)) { vector<Point>P1,P2; for(int i=0;i<n;++i) P1.push_back(Point(read<int>(),read<int>())); for(int i=0;i<m;++i) P2.push_back(Point(read<int>(),read<int>())); if(ConvexPolygonDisjoint(ConvexHull(P1),ConvexHull(P2))) puts("Yes"); else puts("No"); } return 0; }
来源:https://www.cnblogs.com/autoint/p/10162620.html