zoukankan      html  css  js  c++  java
  • uva10256

    uva10256

    题意

    平面上存在两种颜色的点,问是否存在一条直线,使得任取一个红点和一个蓝点都在直线的异侧,这条直线不经过任何点。

    分析

    对每种颜色的点求一发凸包,问题等价于判断两个多边形是否相交或相切。

    1. 判断是否有边相交
    2. 判断是否有点在另一个多边形内或边上

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const double INF = 1e18;
    const int MAXN = 6e2 + 10;
    const double EPS = 1e-9;
    int Sgn(double x) {
        if(fabs(x) < EPS) return 0;
        return x < 0 ? -1 : 1;
    }
    struct Point {
        double x, y;
        Point(double x = 0, double y = 0) : x(x), y(y) {}
        bool operator < (const Point& p1) const {
            if(x == p1.x) return y < p1.y;
            return x < p1.x;
        }
        void read_point() {
            scanf("%lf%lf", &x, &y);
        }
    };
    typedef Point Vector;
    double Dot(Point p1, Point p2) {
        return p1.x * p2.x + p1.y * p2.y;
    }
    double Cross(Point p1, Point p2) {
        return p1.x * p2.y - p1.y * p2.x;
    }
    Point operator - (Point p1, Point p2) {
        return Point(p1.x - p2.x, p1.y - p2.y);
    }
    // 判断点是否在线段上(不包括端点)
    bool OnSegment(Point P, Point a1, Point a2) {
        Vector v1 = a1 - P, v2 = a2 - P;
        return Sgn(Cross(v1, v2)) == 0 && Sgn(Dot(v1, v2)) < 0;
    }
    bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
        double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1);
        double c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
        return Sgn(c1) * Sgn(c2) < 0 && Sgn(c3) * Sgn(c4) < 0;
    }
    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;
    }
    //判定点P是否在多边形内部
    int isPointInPolygon(Point P, Point* Poly, int n) {
        int wn = 0;
        for(int i = 0; i < n; ++i) {
            if(OnSegment(P, Poly[i], Poly[(i + 1) % n])) return -1; //在边界上
            int k = Sgn(Cross(Poly[(i + 1) % n] - Poly[i], P - Poly[i]));
            int d1 = Sgn(Poly[i].y - P.y);
            int d2 = Sgn(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 1; //内部
        return 0;             //外部
    }
    
    Point p1[MAXN], p2[MAXN], ch1[MAXN], ch2[MAXN];
    int main() {
        int n, m;
        while(~scanf("%d%d", &n, &m) && (n + m)) {
            for(int i = 0; i < n; i++) {
                p1[i].read_point();
            }
            for(int i = 0; i < m; i++) {
                p2[i].read_point();
            }
            int nn = ConvexHull(p1, n, ch1);
            int mm = ConvexHull(p2, m, ch2);
            int flg = 1;
            for(int i = 0; i < nn; i++) {
                if(isPointInPolygon(ch1[i], ch2, mm)) flg = 0;
                for(int j = 0; j < mm; j++) {
                    if(SegmentProperIntersection(ch1[i], ch1[(i + 1) % nn], ch2[j], ch2[(j + 1) % mm])) {
                        flg = 0;
                    }
                }
            }
            for(int i = 0; i < mm; i++) {
                if(isPointInPolygon(ch2[i], ch1, nn)) flg = 0;
            }
            puts(flg ? "Yes" : "No");
        }
        return 0;
    }
    
  • 相关阅读:
    前台Json格式中时间的格式转换
    存储过程
    自定义注解
    递归(累加)
    java操作符
    Markdown语法参考
    for表达式的循环执行顺序
    java形参与作用域
    java引用类型数组的创建方式
    学习总结之Log4NET
  • 原文地址:https://www.cnblogs.com/ftae/p/7384680.html
Copyright © 2011-2022 走看看