• uva 10256 The Great Divide


    题意:给定两个点集,一个红点集,另一个蓝点集,询问,能否找到一条直线能,使得任取一个红点和蓝点都在直线异侧。

    思路:划分成两个凸包,一个红包,一个蓝包。两个凸包不相交不重合。

    1.任取一个凸包中的点不在另一个凸包中。

    2.任取一个凸包中的边与另一个凸包不相交。

      1 #include<cstdio>
      2 #include<cmath>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<iostream>
      6 #include<memory.h>
      7 #include<cstdlib>
      8 #include<vector>
      9 #define clc(a,b) memset(a,b,sizeof(a))
     10 #define LL long long int
     11 #define up(i,x,y) for(i=x;i<=y;i++)
     12 #define w(a) while(a)
     13 using namespace std;
     14 const double inf=0x3f3f3f3f;
     15 const int N = 4010;
     16 const double eps = 5*1e-13;
     17 const double PI = acos(-1.0);
     18 
     19 double dcmp(double x)
     20 {
     21     if(fabs(x) < eps) return 0;
     22     else return x < 0 ? -1 : 1;
     23 }
     24 
     25 struct Point
     26 {
     27     double x, y;
     28     Point(double x=0, double y=0):x(x),y(y) { }
     29 };
     30 
     31 typedef Point Vector;
     32 
     33 Vector operator - (const Point& A, const Point& B)
     34 {
     35     return Vector(A.x-B.x, A.y-B.y);
     36 }
     37 
     38 double Cross(const Vector& A, const Vector& B)
     39 {
     40     return A.x*B.y - A.y*B.x;
     41 }
     42 
     43 double Dot(const Vector& A, const Vector& B)
     44 {
     45     return A.x*B.x + A.y*B.y;
     46 }
     47 
     48 bool operator < (const Point& p1, const Point& p2)
     49 {
     50     return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
     51 }
     52 
     53 bool operator == (const Point& p1, const Point& p2)
     54 {
     55     return p1.x == p2.x && p1.y == p2.y;
     56 }
     57 
     58 bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
     59 {
     60     double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
     61            c3 = Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
     62     return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
     63 }
     64 
     65 bool OnSegment(const Point& p, const Point& a1, const Point& a2)
     66 {
     67     return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
     68 }
     69 
     70 // 点集凸包
     71 // 如果不希望在凸包的边上有输入点,把两个 <= 改成 <
     72 // 如果不介意点集被修改,可以改成传递引用
     73 vector<Point> ConvexHull(vector<Point> p)
     74 {
     75     // 预处理,删除重复点
     76     sort(p.begin(), p.end());
     77     p.erase(unique(p.begin(), p.end()), p.end());
     78 
     79     int n = p.size();
     80     int m = 0;
     81     vector<Point> ch(n+1);
     82     for(int i = 0; i < n; i++)
     83     {
     84         while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
     85         ch[m++] = p[i];
     86     }
     87     int k = m;
     88     for(int i = n-2; i >= 0; i--)
     89     {
     90         while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
     91         ch[m++] = p[i];
     92     }
     93     if(n > 1) m--;
     94     ch.resize(m);
     95     return ch;
     96 }
     97 
     98 int IsPointInPolygon(const Point& p, const vector<Point>& poly)
     99 {
    100     int wn = 0;
    101     int n = poly.size();
    102     for(int i = 0; i < n; i++)
    103     {
    104         const Point& p1 = poly[i];
    105         const Point& p2 = poly[(i+1)%n];
    106         if(p1 == p || p2 == p || OnSegment(p, p1, p2)) return -1; // 在边界上
    107         int k = dcmp(Cross(p2-p1, p-p1));
    108         int d1 = dcmp(p1.y - p.y);
    109         int d2 = dcmp(p2.y - p.y);
    110         if(k > 0 && d1 <= 0 && d2 > 0) wn++;
    111         if(k < 0 && d2 <= 0 && d1 > 0) wn--;
    112     }
    113     if (wn != 0) return 1; // 内部
    114     return 0; // 外部
    115 }
    116 
    117 bool ConvexPolygonDisjoint(const vector<Point> ch1, const vector<Point> ch2)
    118 {
    119     int c1 = ch1.size();
    120     int c2 = ch2.size();
    121     for(int i = 0; i < c1; i++)
    122         if(IsPointInPolygon(ch1[i], ch2) != 0) return false; // 内部或边界上
    123     for(int i = 0; i < c2; i++)
    124         if(IsPointInPolygon(ch2[i], ch1) != 0) return false; // 内部或边界上
    125     for(int i = 0; i < c1; i++)
    126         for(int j = 0; j < c2; j++)
    127             if(SegmentProperIntersection(ch1[i], ch1[(i+1)%c1], ch2[j], ch2[(j+1)%c2])) return false;
    128     return true;
    129 }
    130 
    131 int main()
    132 {
    133     int n, m;
    134     while(scanf("%d%d", &n, &m) == 2 && n > 0 && m > 0)
    135     {
    136         vector<Point> P1, P2;
    137         double x, y;
    138         for(int i = 0; i < n; i++)
    139         {
    140             scanf("%lf%lf", &x, &y);
    141             P1.push_back(Point(x, y));
    142         }
    143         for(int i = 0; i < m; i++)
    144         {
    145             scanf("%lf%lf", &x, &y);
    146             P2.push_back(Point(x, y));
    147         }
    148         if(ConvexPolygonDisjoint(ConvexHull(P1), ConvexHull(P2)))
    149             printf("Yes
    ");
    150         else
    151             printf("No
    ");
    152     }
    153     return 0;
    154 }
    View Code
  • 相关阅读:
    spark集群安装部署
    CentOS7 下安装GUI图形界面GNOME
    Wininet请求包装类简稿
    Wininet下载类初稿
    MAC 编制计划任务
    弹出式窗口管理单元备忘
    rc资源文件的中英文应用备忘
    自备工具库
    界面方面的备忘
    多屏开发的备忘
  • 原文地址:https://www.cnblogs.com/ITUPC/p/4883853.html
Copyright © 2020-2023  润新知