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;
}
原文地址:https://www.cnblogs.com/ftae/p/7384680.html