UVA 10256 The Great Divide (凸包,多边形的位置关系)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148

【思路】

凸包

求出红蓝点的凸包,剩下的问题就是判断两个凸包是否相离。

需要确定两点:

    1)  凸包上线段是否相交->相交

    2)  凸包上的点是否包含在另一个凸包里->内含。

【代码】

  1 #include<cmath>
  2 #include<vector>
  3 #include<cstdio>
  4 #include<algorithm>
  5 using namespace std;
  6
  7 const double eps = 1e-10;
  8 int dcmp(double x) {
  9     if(fabs(x)<eps) return 0; else return x<0? -1:1;
 10 }
 11
 12 struct Pt {
 13     double x,y;
 14     Pt(double x=0,double y=0):x(x),y(y) {};
 15 };
 16 typedef Pt vec;
 17 vec operator - (Pt A,Pt B) { return vec(A.x-B.x,A.y-B.y); }
 18 bool operator == (Pt A,Pt B) {
 19     return dcmp(A.x-B.x)==0 && dcmp(A.y-B.y)==0;
 20 }
 21 bool operator < (const Pt& a,const Pt& b) {
 22     return a.x<b.x || (a.x==b.x && a.y<b.y);
 23 }
 24 double Dot(vec A,vec B) { return A.x*B.x+A.y*B.y;}
 25 double cross(Pt A,Pt B) { return A.x*B.y-A.y*B.x; }
 26
 27 bool SegIntersection(Pt a1,Pt a2,Pt b1,Pt b2) {
 28     double c1 = cross(a2-a1,b1-a1), c2 = cross(a2-a1,b2-a1),
 29              c3 = cross(b2-b1,a1-b1), c4=cross(b2-b1,a2-b1);
 30   return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
 31 }
 32 bool OnSeg(Pt p,Pt a1,Pt a2) {
 33     return dcmp(cross(p-a1,p-a2))==0 && dcmp(Dot(p-a1,p-a2))<0;
 34 }
 35
 36
 37 int n;
 38 vector<Pt> ConvexHull(vector<Pt> p) {
 39     sort(p.begin(),p.end());
 40     p.erase(unique(p.begin(),p.end()),p.end());
 41     int n=p.size();
 42     int m=0;
 43     vector<Pt> ch(n+1);
 44     for(int i=0;i<n;i++) {
 45         while(m>1 && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
 46         ch[m++]=p[i];
 47     }
 48     int k=m;
 49     for(int i=n-2;i>=0;i--) {
 50         while(m>k && cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
 51         ch[m++]=p[i];
 52     }
 53     if(n>1) m--;
 54     ch.resize(m);
 55     return ch;
 56 }
 57
 58 int IsPointinPolygon(Pt p,vector<Pt>& poly) {
 59     int wn=0;
 60     int n=poly.size();
 61     for(int i=0;i<n;i++) {
 62         Pt& p1=poly[i];
 63         Pt& p2=poly[(i+1)%n];
 64         if(p1==p || p2==p || OnSeg(p,p1,p2)) return -1;
 65         int k=dcmp(cross(p2-p1,p-p1));
 66         int d1=dcmp(p1.y-p.y);
 67         int d2=dcmp(p2.y-p.y);
 68         if(k>0 && d1<=0 && d2>0) wn++;
 69         if(k<0 && d2<=0 && d1>0) wn--;
 70     }
 71     if(wn!=0) return 1;
 72     return 0;
 73 }
 74 bool ConvexPolygonDisjoint(vector<Pt> ch1,vector<Pt> ch2) {
 75     int c1=ch1.size() , c2=ch2.size();
 76     for(int i=0;i<c1;i++)
 77         if(IsPointinPolygon(ch1[i],ch2)!=0) return false;
 78     for(int i=0;i<c2;i++)
 79         if(IsPointinPolygon(ch2[i],ch1)!=0) return false;
 80     for(int i=0;i<c1;i++)
 81         for(int j=0;j<c2;j++)
 82             if(SegIntersection(ch1[i],ch1[(i+1)%c1],ch2[j],ch2[(j+1)%c2])) return false;
 83     return true;
 84 }
 85
 86 int main() {
 87     int n,m;
 88     while(scanf("%d%d",&n,&m)==2 && n && m) {
 89         vector<Pt> P1,P2;
 90         double x,y;
 91         for(int i=0;i<n;i++) {
 92             scanf("%lf%lf",&x,&y);
 93             P1.push_back(Pt(x,y));
 94         }
 95         for(int i=0;i<m;i++) {
 96             scanf("%lf%lf",&x,&y);
 97             P2.push_back(Pt(x,y));
 98         }
 99         if(ConvexPolygonDisjoint(ConvexHull(P1),ConvexHull(P2)))
100             puts("Yes"); else puts("No");
101     }
102     return 0;
103 }
时间: 2024-10-09 23:46:09

UVA 10256 The Great Divide (凸包,多边形的位置关系)的相关文章

UVA 10256 The Great Divide(凸包划分)

The Great Divide Input: standard input Output: standard output Time Limit: 8 seconds Memory Limit: 32 MB Somewhere in Gaul, there is a little village very like the village where Asterix and Obelix live. Not very long ago they had only one chief Altru

UVa 10256 The Great Divide,判断两个凸包是否相离

先从给出的两个点集中分别计算出两个凸包, 然后判断两个凸包是否相离. #include<cstdio> #include<vector> #include<cmath> #include<algorithm> using namespace std; const double eps = 1e-10; double dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -

LightOj1190 - Sleepwalking(判断点与多边形的位置关系--射线法模板)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1190 题意:给你一个多边形含有n个点:然后又m个查询,每次判断点(x, y)是否在多边形的内部; 射线法判断即可适用于任何(凸或凹)多边形;时间复杂度为O(n); 判断一个点是在多边形内部,边上还是在外部,时间复杂度为O(n):射线法可以正确用于凹多边形: 射线法是使用最广泛的算法,这是由于相比较其他算法而言,它不但可以正确使用在凹多边形上,而且不需要考虑精度误差问题.该算法思想是从

Cupid&#39;s Arrow---hdu1756(判断点与多边形的位置关系 模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1756 题意:中文题,套模板即可: /* 射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为O(n): 射线法可以正确用于凹多边形: 射线法是使用最广泛的算法,这是由于相比较其他算法而言,它不但可以正 确使用在凹多边形上,而且不需要考虑精度误差问题.该算法思想是从点出 发向右水平做一条射线,计算该射线与多边形的边的相交点个数,当点不在 多边形边上时,如果是奇数,那么点就一定在多边形内部,否

UVA 10256 The Great Divide (判断凸包相交)

题目链接:UVA 10256 题意 有n个红点和m个蓝点,问是否存在一条直线能够分开红点和蓝点. 题解 分别求出红点和蓝点的凸包,判断两个凸包是否相交. 凸包不相交的条件: 凸包上的任意点都在另一个凸包的外面 凸包的任意线段都与另一个凸包不相交 代码 #include <bits/stdc++.h> using namespace std; const double eps = 1e-8; const double pi = acos(-1.0); class Point { public:

ZOJ1081 Points Within 点和多边形的位置关系

ZOJ1081 给一个点和一个多边形 判断点在多边形内(边上)还是在多边形外 在多边形外的点引一条射线必然穿过多边形的两条边 而在多边形内的点则不一定. 当然凹多边形有特殊情况 但是总能找到对应位置关系的边来抵消 #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm>

UVa 10256 (判断两个凸包相离) The Great Divide

题意: 给出n个红点,m个蓝点.问是否存在一条直线使得红点和蓝点分别分布在直线的两侧,这些点不能再直线上. 分析: 求出两种点的凸包,如果两个凸包相离的话,则存在这样一条直线. 判断凸包相离需要判断这两件事情: 任何一个凸包的任何一个顶点不能在另一个凸包的内部或者边界上. 两个凸包的任意两边不能相交. 二者缺一不可,第一条很好理解,但为什么还要判断第二条,因为存在这种情况: 虽然每个凸包的顶点都在另一个凸包的外部,但两个凸包明显是相交的. 1 //#define LOCAL 2 #include

uva 10256 The Great Divide

题意:给定两个点集,一个红点集,另一个蓝点集,询问,能否找到一条直线能,使得任取一个红点和蓝点都在直线异侧. 思路:划分成两个凸包,一个红包,一个蓝包.两个凸包不相交不重合. 1.任取一个凸包中的点不在另一个凸包中. 2.任取一个凸包中的边与另一个凸包不相交. 1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostrea

计算几何线,点,多边形,位置关系较全模板

const double eps = 1e-6; int sgn(double x) { if(fabs(x) < eps)return 0; if(x < 0)return -1; else return 1; } struct Point { double x,y; Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(