POJ 3410 Split convex polygon(凸包)

题意是逆时针方向给你两个多边形,问你这两个多边形通过旋转和平移能否拼成一个凸包。

首先可以想到的便是枚举边,肯定是有一对长度相同的边贴合,那么我们就可以n2枚举所有边对,接下来就是旋转点对,那么假设多边型在这条向量的左侧,那么我们可以根据叉积正负判断旋转的方向。

然后就是如何判断了,显然有一种情况是凸包里扣除整个多边形,那么这种情况我们需要对重合的边进行删除,可以发现,如果有重合的边,他一定是成对出现,有一条进去的边也有一条出来的边,那么我们可以直接通过vector不断插入的过程和之前那条边比较,是否是同一对点产生的边,如果是我们就直接抵消,进行下一次判断。

最后就是对这些绕着一圈的点进行判断是否是凸包,那么我们直接绕一圈判断两个向量叉积是否是小于0或者叉积等于0但是方向相反,那么这种情况也是非法。

还是有很多细节地方,此题好像eps要开大一点,不然会wa。

 

 

 

12
0 0
10 0
10 4
6 4
8 2
4 2
4 8
8 8
6 6
10 6
10 10
0 10
12
12 4
12 6
10 10
10 6
6 6
8 8
4 8
4 2
8 2
6 4
10 4
10 0

ans=1

12
0 0
10 0
10 4
6 4
8 2
4 2
4 8
8 8
6 6
10 6
10 10
0 10
8
12 4
12 6
6 6
8 8
4 8
4 2
8 2
6 4

ans=0
  1 //      ——By DD_BOND
  2 
  3 //#include<bits/stdc++.h>
  4 //#include<unordered_map>
  5 //#include<unordered_set>
  6 #include<functional>
  7 #include<algorithm>
  8 #include<iostream>
  9 //#include<ext/rope>
 10 #include<iomanip>
 11 #include<climits>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<cstddef>
 15 #include<cstdio>
 16 #include<memory>
 17 #include<vector>
 18 #include<cctype>
 19 #include<string>
 20 #include<cmath>
 21 #include<queue>
 22 #include<deque>
 23 #include<ctime>
 24 #include<stack>
 25 #include<map>
 26 #include<set>
 27 
 28 #define fi first
 29 #define se second
 30 #define pb push_back
 31 #define MP make_pair
 32 
 33 using namespace std;
 34 
 35 typedef double db;
 36 typedef long ll;
 37 typedef pair<db,db> Pd;
 38 typedef pair<int,int> P;
 39 typedef pair<ll,ll> Pll;
 40 
 41 const db eps=1e-6;
 42 const int MAXN=1e3+10;
 43 const db pi=acos(-1.0);
 44 const ll INF=0x3f3f3f3f3f3f3f3f;
 45 
 46 inline int dcmp(db x){
 47     if(fabs(x)<eps) return 0;
 48     return (x>0? 1: -1);
 49 }
 50 
 51 inline db Sqrt(db x){
 52     return x>0? sqrt(x): 0;
 53 }
 54 
 55 inline db sqr(db x){ return x*x; }
 56 
 57 struct Point{
 58     db x,y;
 59     Point(){ x=0,y=0; }
 60     Point(db _x,db _y):x(_x),y(_y){}
 61     void input(){
 62         double _x,_y;
 63         scanf("%lf%lf",&_x,&_y);
 64         x=_x,y=_y;
 65     }
 66     bool operator ==(const Point &b)const{
 67         return (dcmp(x-b.x)==0&&dcmp(y-b.y)==0);
 68     }
 69     bool operator <(const Point &b)const{
 70         return (dcmp(x-b.x)==0? dcmp(y-b.y)<0 : x<b.x);
 71     }
 72     Point operator +(const Point &b)const{
 73         return Point(x+b.x,y+b.y);
 74     }
 75     Point operator -(const Point &b)const{
 76         return Point(x-b.x,y-b.y);
 77     }
 78     Point operator *(db a){
 79         return Point(x*a,y*a);
 80     }
 81     Point operator /(db a){
 82         return Point(x/a,y/a);
 83     }
 84     db len2(){  //长度平方
 85         return sqr(x)+sqr(y);
 86     }
 87     db len(){   //长度
 88         return Sqrt(len2());
 89     }
 90     db polar(){ //向量的极角
 91         return atan2(y,x);   //返回与x轴正向夹角(-pi~pi]
 92     }
 93     Point change_len(db r){ //转化为长度为r的向量
 94         db l=len();
 95         if(dcmp(l)==0)  return *this;  //零向量
 96         return Point(x*r/l,y*r/l);
 97     }
 98     Point rotate(Point p,db ang){   //绕点p逆时针旋转ang度
 99         Point v=(*this)-p;
100         db c=cos(ang),s=sin(ang);
101         return Point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
102     }
103 };
104 
105 inline db cross(Point a,Point b){   //叉积
106     return a.x*b.y-a.y*b.x;
107 }
108 
109 inline db dot(Point a,Point b){ //点积
110     return a.x*b.x+a.y*b.y;
111 }
112 
113 inline db dis(Point a,Point b){ //两点的距离
114     Point p=b-a;    return p.len();
115 }
116 
117 db rad(Point a,Point b){    //两个向量的夹角
118     return fabs(atan2(fabs(cross(a,b)),dot(a,b)));
119 }
120 
121 struct Node{
122     Point vec,s,t;
123     Node(){}
124     Node(Point a,Point b,Point c){
125         vec=a,s=b,t=c;
126     }
127 };
128 
129 Point a[210],b[210],tmp[410];
130 
131 int main(void){
132     int n;  
133     while(~scanf("%d",&n)){
134         int ans=0;
135         for(int i=0;i<n;i++)    a[i].input(),a[i+n]=a[i];
136         int m;  scanf("%d",&m);
137         for(int i=0;i<m;i++)    b[i].input(),b[i+m]=b[i];
138 
139         for(int i=0;i<n;i++)
140             for(int j=0;j<m;j++)
141                 if(dcmp(dis(a[i],a[i+1])-dis(b[j],b[j+1]))==0){
142                     int p=0,f=0; 
143                     vector<Node>st;
144                     db ang=rad(b[j+1]-b[j],a[i+1]-a[i]);
145                     if(dcmp(cross(b[j+1]-b[j],a[i+1]-a[i]))>=0)  ang-=pi;
146                     else    ang=pi-ang;
147 
148                     for(int k=0;k<i;k++)        tmp[p++]=a[k];
149                     for(int k=j+1;k<j+m+1;k++)  tmp[p++]=a[i+1]+(b[k]-b[j]).rotate(Point(0,0),ang);
150                     for(int k=i+2;k<n;k++)      tmp[p++]=a[k];
151 
152                     tmp[p]=tmp[0];
153 
154                     for(int i=0;i<p;i++){
155                         Point res=tmp[i+1]-tmp[i];
156                         if(st.size()&&st.back().t==tmp[i]&&st.back().s==tmp[i+1])   st.pop_back();
157                         else    st.pb(Node(res,tmp[i],tmp[i+1]));
158                     }
159 
160                     st.pb(st[0]);
161                     for(int i=1;i<(int)st.size();i++)
162                         if(dcmp(cross(st[i-1].vec,st[i].vec))<0||
163                           (dcmp(cross(st[i-1].vec,st[i].vec))==0&&dcmp(dot(st[i-1].vec,st[i].vec))<=0))
164                             f=1;
165                     if(!f)  ans=1;
166                 }
167         printf("%d\n",ans);
168     }
169     return 0;
170 }
posted @ 2019-10-11 23:28  DD_BOND  阅读(279)  评论(0编辑  收藏  举报