The Great Divide
Input: standard input
Output: standard output
Time Limit: 8 seconds
Memory Limit: 32 MB
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 invitedGetafix, the venerable druid of Asterix’s village, to figure out whether such a dividing line exists or not.
Getafix
Since Getafix knows that you are so good in programming, he seeks your help.
Input
The input may contain multiple test cases.
The first line of each test case contains two integers M and C (1 £ M, C £ 500), indicating the number of houses of the supporters ofMajestix and Cleverdix respectively.
Each of the next M lines contains two integers x and y (-1000 £ x, y £ 1000) giving the co-ordinates of the house of a supporter ofMajestix. For convenience each house is considered as a single point on the plane.
Each of the next C lines contains two integers x and y (-1000 £ x, y £ 1000) giving the co-ordinates of the house of a supporter ofCleverdix.
The input will terminate with two zeros for M and C.
Output
For each test case in the input output a line containing either “Yes” or “No” depending on whether there exists a straight line that divides the two set of houses. The dividing line can NOT contain points of both sides.
Sample Input
4 3
100 600
200 400
600 500
300 700
400 100
600 200
500 300
4 3
100 600
400 100
600 200
500 300
200 400
600 500
300 700
0 0
Sample Output
Yes
No
判断两个点集是否相交,即有没有一条线段可以划分两个点集。
先求出凸包。
判断凸包中是否有一点在另一个凸包内。
判断凸包内是否有任意两条线段相交。
注意下,按坐标排序的时候要用dcmp来写。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 533 ; const double eps = 1e-10 ; int n1 , n2 ; int dcmp( double x ) { if( fabs(x)<eps) return 0 ; return x<0?-1:1;} struct Point { double x , y ; Point(){}; Point( double a, double b ) { x=a ,y=b; } bool operator < ( const Point &a ) const { return dcmp(x-a.x)<0 ||(dcmp(x-a.x)==0 && dcmp(y-a.y)<0); } }p1[N],p2[N],ch1[N],ch2[N]; Point operator - ( Point a , Point b ) { return Point(a.x-b.x,a.y-b.y); } Point operator + ( Point a , Point b ) { return Point(a.x+b.x,a.y+b.y); } double Cross( Point a , Point b ) { return a.x*b.y-a.y*b.x; } double Dot( Point a , Point b ) { return a.x*b.x+a.y*b.y; } //test bool isPointOnSegment( Point p , Point a1 , Point a2 ) { return dcmp( Cross(a1-p,a2-p)) == 0 && dcmp(Dot(a1-p,a2-p)) < 0 ; } bool SegmentProperIntersection(Point a1 , Point a2 , Point b1 , 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 isPointInPolygon( Point p , Point* poly , int n ) { int wn = 0 ; for( int i = 0 ; i < n ; ++i ) { if( isPointOnSegment( p , poly[i] , poly[(i+1)%n] ) ) return true; int k = dcmp( Cross( poly[(i+1)%n]-poly[i] , p - poly[i] ) ); int d1 = dcmp( poly[i].y - p.y ); int d2 = dcmp( poly[(i+1)%n].y - p.y ); if( k > 0 && d1<= 0 && d2 > 0 ) wn++ ; if( k < 0 && d2 <= 0 && d1 > 0 ) wn--; } if( wn != 0 ) return true; // inside return false; //outside } int ConvexHull(Point *p,int n,Point *ch) { sort(p,p+n); int m=0; 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--; return m; } void Run() { for( int i = 0 ; i < n1 ; ++i ){ scanf("%lf%lf",&p1[i].x,&p1[i].y); } for( int i = 0 ; i < n2 ; ++i ){ scanf("%lf%lf",&p2[i].x,&p2[i].y); } int m1 = ConvexHull(p1,n1,ch1), m2 = ConvexHull(p2,n2,ch2); for( int i = 0 ; i < m1 ; ++i ) if( isPointInPolygon(ch1[i],ch2,m2) ) { puts("No"); return ;} for( int i = 0 ; i < m2 ; ++i ) if( isPointInPolygon(ch2[i],ch1,m1) ) { puts("No"); return ;} for( int i = 0 ; i < m1 ; ++i ) { for( int j = 0 ; j < m2 ; ++j ){ if( SegmentProperIntersection( ch1[i],ch1[(i+1)%m1],ch2[j],ch2[(j+1)%m2]) ){ puts("No"); return ; } } } puts("Yes"); } int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL while( scanf("%d%d",&n1,&n2) ==2 && n1 )Run(); }