UVA 10256 The Great Divide (凸包,多边形的位置关系)

时间:2023-03-08 15:51:00

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148

【思路】

凸包

求出红蓝点的凸包,剩下的问题就是判断两个凸包是否相离。

需要确定两点:

    1)  凸包上线段是否相交->相交

    2)  凸包上的点是否包含在另一个凸包里->内含。

【代码】

 #include<cmath>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std; const double eps = 1e-;
int dcmp(double x) {
if(fabs(x)<eps) return ; else return x<? -:;
} struct Pt {
double x,y;
Pt(double x=,double y=):x(x),y(y) {};
};
typedef Pt vec;
vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
bool operator == (Pt A,Pt B) {
return dcmp(A.x-B.x)== && dcmp(A.y-B.y)==;
}
bool operator < (const Pt& a,const Pt& b) {
return a.x<b.x || (a.x==b.x && a.y<b.y);
}
double Dot(vec A,vec B) { return A.x*B.x+A.y*B.y;}
double cross(Pt A,Pt B) { return A.x*B.y-A.y*B.x; } bool SegIntersection(Pt a1,Pt a2,Pt b1,Pt 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)< && dcmp(c3)*dcmp(c4)<;
}
bool OnSeg(Pt p,Pt a1,Pt a2) {
return dcmp(cross(p-a1,p-a2))== && dcmp(Dot(p-a1,p-a2))<;
} int n;
vector<Pt> ConvexHull(vector<Pt> p) {
sort(p.begin(),p.end());
p.erase(unique(p.begin(),p.end()),p.end());
int n=p.size();
int m=;
vector<Pt> ch(n+);
for(int i=;i<n;i++) {
while(m> && cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-;i>=;i--) {
while(m>k && cross(ch[m-]-ch[m-],p[i]-ch[m-])<=) m--;
ch[m++]=p[i];
}
if(n>) m--;
ch.resize(m);
return ch;
} int IsPointinPolygon(Pt p,vector<Pt>& poly) {
int wn=;
int n=poly.size();
for(int i=;i<n;i++) {
Pt& p1=poly[i];
Pt& p2=poly[(i+)%n];
if(p1==p || p2==p || OnSeg(p,p1,p2)) return -;
int k=dcmp(cross(p2-p1,p-p1));
int d1=dcmp(p1.y-p.y);
int d2=dcmp(p2.y-p.y);
if(k> && d1<= && d2>) wn++;
if(k< && d2<= && d1>) wn--;
}
if(wn!=) return ;
return ;
}
bool ConvexPolygonDisjoint(vector<Pt> ch1,vector<Pt> ch2) {
int c1=ch1.size() , c2=ch2.size();
for(int i=;i<c1;i++)
if(IsPointinPolygon(ch1[i],ch2)!=) return false;
for(int i=;i<c2;i++)
if(IsPointinPolygon(ch2[i],ch1)!=) return false;
for(int i=;i<c1;i++)
for(int j=;j<c2;j++)
if(SegIntersection(ch1[i],ch1[(i+)%c1],ch2[j],ch2[(j+)%c2])) return false;
return true;
} int main() {
int n,m;
while(scanf("%d%d",&n,&m)== && n && m) {
vector<Pt> P1,P2;
double x,y;
for(int i=;i<n;i++) {
scanf("%lf%lf",&x,&y);
P1.push_back(Pt(x,y));
}
for(int i=;i<m;i++) {
scanf("%lf%lf",&x,&y);
P2.push_back(Pt(x,y));
}
if(ConvexPolygonDisjoint(ConvexHull(P1),ConvexHull(P2)))
puts("Yes"); else puts("No");
}
return ;
}