uva10256 The Great Divide


Somewhere in Gaul, there is a little village very like the village where Asterix and Obelix live. Not very long ago they had only one chief Altruistix and peace reigned in the village. But now those happy days are just dreams. The villagers are now divided. Some of the villagers have elected Majestix as their chief and the others have elected Cleverdix . Majestix Cleverdix The two chiefs have decided to divide the village into two parts by digging a straight ditch through the middle of the village so that the houses of the supporters of Majestix lie on one part and those of the followers of Cleverdix lie on the other. So, they have invited Geta x , the venerable druid of Asterix ‘s village, to gure out whether such a dividing line exists or not. Geta x Since Geta x knows that you are so good in PRogramming, he seeks your help. Input The input may contain multiple test cases. The rst line of each test case contains two integers M and C (1  M;C  500), indicating the number of houses of the supporters of Majestix and Cleverdix respectively. Each of the next M lines contains two integers x and y (

先求出两部分点的凸包,问题就是凸包是否有公共部分【是否相离】。 凸包相交,只需要判断每两条边是否相交。 凸包内含,只需要各取一个点判断是否在另一个多边形里面。

#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const double eps=1e-8; int cmp(double x) { if (x>eps) return 1; if (fabs(x)<eps) return 0; return -1; } struct vector { double x,y; void rd() { scanf("%lf%lf",&x,&y); } bool Operator < (const vector &v) const { return cmp(x-v.x)==-1||(cmp(x-v.x)==0&&cmp(y-v.y)==-1); } bool operator == (const vector &v) { return cmp(x-v.x)==0&&cmp(y-v.y)==0; } vector operator + (const vector &v) const { return (vector){x+v.x,y+v.y}; } vector operator - (const vector &v) const { return (vector){x-v.x,y-v.y}; } vector operator * (const double &k) const { return (vector){x*k,y*k}; } vector operator / (const double &k) const { return (vector){x/k,y/k}; } }a[510],b[510],tem[510]; typedef vector point; double dot(vector v1,vector v2) { return v1.x*v2.x+v1.y*v2.y; } double cross(vector v1,vector v2) { return v1.x*v2.y-v1.y*v2.x; } struct seg { point a,b; }; bool onseg(point p,seg s) { return p==s.a||p==s.b||(cmp(dot(s.b-s.a,p-s.a))==0&&cmp(dot(p-s.a,p-s.b))==-1); } bool intersect(seg s1,seg s2) { if (onseg(s1.a,s2)||onseg(s1.b,s2)||onseg(s2.a,s1)||onseg(s2.b,s1)) return 1; int c1=cmp(cross(s2.b-s2.a,s1.a-s2.a)),c2=cmp(cross(s2.b-s2.a,s1.b-s2.a)), c3=cmp(cross(s1.b-s1.a,s2.a-s1.a)),c4=cmp(cross(s1.b-s1.a,s2.b-s1.a)); return c1*c2==-1&&c3*c4==-1; } bool inside(point p,point *a,int n) { int cnt=0; for (int i=1;i<n;i++) { int x=cmp(cross(a[i+1]-a[i],p-a[i])),y=cmp(p.y-a[i].y),z=cmp(p.y-a[i+1].y); if (x==1) { if (y>=0&&z==-1) cnt++; } else { if (z>=0&&y==-1) cnt--; } } return cnt; } int n,m; void solve(int n,point *f,int &nn) { for (int i=1;i<=n;i++) tem[i].rd(); sort(tem+1,tem+n+1); n=unique(tem+1,tem+n+1)-tem-1; nn=0; for (int i=1;i<=n;i++) { while (nn>1&&cmp(cross(f[nn]-f[nn-1],tem[i]-f[nn-1]))==-1) nn--; f[++nn]=tem[i]; } int nnn=nn; for (int i=n-1;i;i--) { while (nn>nnn&&cmp(cross(f[nn]-f[nn-1],tem[i]-f[nn-1]))==-1) nn--; f[++nn]=tem[i]; } } bool solve() { int nn,mm; solve(n,a,nn); solve(m,b,mm); for (int i=1;i<nn;i++) for (int j=1;j<mm;j++) if (intersect((seg){a[i],a[i+1]},(seg){b[j],b[j+1]})) return 0; if (inside(a[1],b,mm)||inside(b[1],a,nn)) return 0; return 1; } int main() { //freopen("in.txt","r",stdin); while (scanf("%d%d",&n,&m)&&n) if (solve()) printf("Yes\n"); else printf("No\n"); }