• UVA 10256 The Great Divide(凸包划分)


    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();
    }
    View Code
    only strive for your goal , can you make your dream come true ?
  • 相关阅读:
    How do I change a .txt file to a .c file?
    [CQOI2007]余数求和
    CSP-J总结&题解
    【CSP游记S】
    [LuoguP1462]通往奥格瑞玛的道路
    归并排序——逆序对
    [NOIP 2011]选择客栈
    [二分图初步]【模板】二分图匹配,匈牙利算法
    [NOIP 2018]旅行
    黑魔法师之门 (magician)-并查集
  • 原文地址:https://www.cnblogs.com/hlmark/p/4149548.html
Copyright © 2020-2023  润新知