zoukankan      html  css  js  c++  java
  • UVA10256 The Great Divide

    怎么又没人写题解,那我来贡献一发好了。

    题目意思很简单,平面上有两种颜色的点,问你能否求出一条直线使两种颜色的点完全分开。

    首先我们考虑两个点集相离的充要条件,这两个点集的凸包必须相离。(很好证明或者画画图理解一下)

    那么怎么判断两个凸包相离,考虑到这里的点的个数不多,我们可以用一种最暴力的方法。

    枚举一个凸包上的所有点所有边,然后判断是否与另一个凸包相离即可。

    点是否在多边形内?直接暴力转角法即可(不推荐射线法,好理解但不好写,精度不高)

    边是否在多边形内,在两个凸包中分别枚举一条边,然后判断是否相交即可。

    稍微注意一下精度问题即可,其实计算几何的题主要考验的就是代码的细节能力。

    CODE

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #define RI register int
    using namespace std;
    typedef double DB;
    const int N=505;
    const DB EPS=1e-10;
    inline int dcmp(DB x)
    {
        if (fabs(x)<EPS) return 0; return x<0?-1:1;
    }
    struct Point
    {
        DB x,y;
        Point(DB X=0,DB Y=0) { x=X; y=Y; }
        inline friend bool operator <(Point A,Point B)
        {
            return dcmp(A.x-B.x)<0||(!dcmp(A.y-B.y)&&dcmp(A.y-B.y)<0);
        }
        inline friend bool operator ==(Point A,Point B)
        {
            return !dcmp(A.x-B.x)&&!dcmp(A.y-B.y);
        }
    }a[N],b[N],cov_a[N],cov_b[N]; int n,m,cnt_a,cnt_b; DB x,y;
    typedef Point Vector;
    inline Vector operator -(Point A,Point B) { return Vector(A.x-B.x,A.y-B.y); }
    class Computation_Geometry
    {
        private:
            inline DB Dot(Vector A,Vector B)
            {
                return A.x*B.x+A.y*B.y;
            }
            inline DB Cross(Vector A,Vector B)
            {
                return A.x*B.y-A.y*B.x;
            }
            inline bool OnSegment(Point p,Point A,Point B)
            {
                return !dcmp(Cross(A-p,B-p))&&dcmp(Dot(A-p,B-p))<0;
            }
            inline bool IsPointInPolygon(Point p,Point *a,int n)
            {
                int t=0; for (RI i=1;i<=n;++i)
                {
                    Point p1=a[i],p2=a[(i+1)%n+1];
                    if (p1==p||p2==p||OnSegment(p,p1,p2)) return 1;
                    int ret=dcmp(Cross(p2-p1,p-p1)),d1=dcmp(p1.y-p.y),d2=dcmp(p2.y-p.y);
                    if (ret>0&&d1<=0&&d2>0) ++t; if (ret<0&&d2<=0&&d1>0) --t;
                }
                return t!=0;
            }
            inline bool SegmentProperIntersection(Point A,Point B,Point C,Point D)
            {
                DB c1=Cross(B-A,C-A),c2=Cross(B-A,D-A),c3=Cross(D-C,A-C),c4=Cross(D-C,B-C);
                return dcmp(c1)*dcmp(c2)<0&&dcmp(c3)*dcmp(c4)<0;
            }
        public:
            inline int ConvexHull(Point *a,int n,Point *p)
            {
                sort(a+1,a+n+1); n=unique(a+1,a+n+1)-a-1; RI i,top=0;
                for (i=1;i<=n;++i)
                {
                    while (top>1&&dcmp(Cross(p[top]-p[top-1],a[i]-p[top]))<=0) --top;
                    p[++top]=a[i];
                }
                int t=top; for (i=n-1;i;--i)
                {
                    while (top>t&&dcmp(Cross(p[top]-p[top-1],a[i]-p[top]))<=0) --top;
                    p[++top]=a[i];
                }
                if (n>1) --top; return top;
            }
            inline bool ConvexPolygonDisjoint(Point *a,int n,Point *b,int m)
            {
                RI i,j; for (i=1;i<=n;++i) if (IsPointInPolygon(a[i],b,m)) return 1;
                for (i=1;i<=m;++i) if (IsPointInPolygon(b[i],a,n)) return 1;
                for (i=1;i<=n;++i) for (j=1;j<=m;++j)
                if (SegmentProperIntersection(a[i],a[i%n+1],b[j],b[j%m+1])) return 1;
                return 0;
            }
    }G;
    int main()
    {
        while (scanf("%d%d",&n,&m),n&&m)
        {
            RI i; for (i=1;i<=n;++i) scanf("%lf%lf",&x,&y),a[i]=Point(x,y);
            for (i=1;i<=m;++i) scanf("%lf%lf",&x,&y),b[i]=Point(x,y);
            cnt_a=G.ConvexHull(a,n,cov_a); cnt_b=G.ConvexHull(b,m,cov_b);
            puts(G.ConvexPolygonDisjoint(cov_a,cnt_a,cov_b,cnt_b)?"No":"Yes");
        };
        return 0;
    }
    
  • 相关阅读:
    Multidimensional Arrays
    TortoiseGit
    Excel教程(14)
    Excel教程(13)
    Excel教程(12)
    Excel教程(11)
    lock
    reflect
    game
    html x
  • 原文地址:https://www.cnblogs.com/cjjsb/p/10305920.html
Copyright © 2011-2022 走看看