特判一下凸包的退化情况就行了。
#include <cstring> #include <cmath> #include <iostream> #include <algorithm> #include <cstdio> using namespace std; typedef unsigned long long ll; #define maxn 511 #define pi acos (-1) #define rotate Rotate const double eps = 1e-8; int dcmp (double x) { if (fabs (x) < eps) return 0; else return x < 0 ? -1 : 1; } struct point { double x, y; point (double _x = 0, double _y = 0) : x(_x), y(_y) {} point operator - (point a) const { return point (x-a.x, y-a.y); } point operator + (point a) const { return point (x+a.x, y+a.y); } bool operator < (const point &a) const { return x < a.x || (x == a.x && y < a.y); } bool operator == (const point &a) const { return dcmp (x-a.x) == 0 && dcmp (y-a.y) == 0; } }; point operator * (point a, double p) { return point (a.x*p, a.y*p); } 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; } int ConvexHull (point *p, point *ch, int n) { 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-1]) <= 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-1]) <= 0) m--; ch[m++] = p[i]; } if (n > 1) m--; return m; } bool OnSegment (point p, point a1, point a2) { //点在线段上 return dcmp (cross (a1-p, a2-p)) == 0 && dcmp (dot (a1-p, a2-p)) <= 0; } bool SegmentIntersection (point a1, point a2, point b1, point b2) { //线段相交 if (OnSegment (a1, b1, b2) || OnSegment (a2, b1, b2) || OnSegment (b1, a1, a2) || OnSegment (b2, a1, a2)) return 1; 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; } int PointInPolygon (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 = 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 1; return 0; } int n, m, cnt1, cnt2; point p1[maxn], p2[maxn], ch1[maxn], ch2[maxn]; bool check () { if (cnt1 == 1) { if (cnt2 == 1 && ch1[0] == ch2[0]) //两个相同的点 return 0; if (cnt2 == 2 && OnSegment (ch1[0], ch2[0], ch2[1])) //点在线段上 return 0; else if (PointInPolygon (ch1[0], ch2, cnt2)) //点在凸包内 return 0; return 1; } if (cnt1 == 2) { if (cnt2 == 1 && OnSegment (ch2[0], ch1[0], ch1[1])) return 0; else if (cnt2 == 2 && SegmentIntersection (ch1[0], ch1[1], ch2[0], ch2[1])) //线段相交 return 0; } if (PointInPolygon (ch2[0], ch1, cnt1) || PointInPolygon (ch1[0], ch2, cnt2)) return 0; for (int i = 0; i < cnt1; i++) { for (int j = 0; j < cnt2; j++) { if (SegmentIntersection (ch1[i], ch1[(i+1)%cnt1], ch2[j], ch2[(j+1)%cnt2])) return 0; } } return 1; } int main () { //freopen ("in", "r", stdin); ios::sync_with_stdio(0); while (cin >> n >> m) { if (n == 0 && m == 0) break; for (int i = 0; i < n; i++) cin >> p1[i].x >> p1[i].y; for (int i = 0; i < m; i++) cin >> p2[i].x >> p2[i].y; cnt1 = ConvexHull (p1, ch1, n); cnt2 = ConvexHull (p2, ch2, m); if (check ()) printf ("Yes\n"); else printf ("No\n"); } return 0; }