码迷,mamicode.com
首页 > 其他好文 > 详细

uva 10256 The Great Divide

时间:2015-10-15 23:37:29      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:

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

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

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\n");
150         else
151             printf("No\n");
152     }
153     return 0;
154 }
View Code

 

uva 10256 The Great Divide

标签:

原文地址:http://www.cnblogs.com/ITUPC/p/4883853.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!