【半平面交模板】bzoj2618 [Cqoi2006]凸多边形

理解好求两直线交点的公式      

单调队列最后用 队尾弹队首 队首弹队尾

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=500+5;   const double eps=1e-8;
int dcmp(double x)
  {if(fabs(x)<=eps) return 0;
   if(x>0)          return 1;
   return -1;
  } 
 
int n,head,tail,m,cnt;  double ans;
struct point 
  {double x,y;
   point operator + (point r) const{point t; t.x=x+r.x; t.y=y+r.y; return t;}
   point operator - (point r) const{point t; t.x=x-r.x; t.y=y-r.y; return t;}
  double operator * (point r) const{return x*r.y-y*r.x;}
   point operator * (double r)const{point t; t.x=x*r; t.y=y*r; return t;}
  }b[N];
   
struct line 
 {point p1,p2; double th;
   bool operator <(line b) const
     {if(dcmp(th-b.th)==0) return dcmp((p2-p1)*(b.p2-p1))<0;
                           return dcmp(th-b.th)<0;
     }
 }a[N],q[N];
  
inline point get(line a,line b)
 {point va=a.p2-a.p1,
        vb=b.p2-b.p1,
         u=b.p1-a.p1;
  point re=b.p1+vb*((u*va)/(va*vb));
  return re; 
 } 
inline bool judge(line a,line b,line k)
 {point p=get(a,b);
  return dcmp((k.p2-k.p1)*(p-k.p1))<0;
 } 
inline void half()
 {sort(a+1,a+m+1);
  for(int i=1;i<=m;i++) if(dcmp(a[i].th-a[i-1].th)!=0) a[++cnt]=a[i];
   
  head=1; tail=0; 
  q[++tail]=a[1]; q[++tail]=a[2];
  for(int i=3;i<=cnt;i++)
   {while(head<tail && judge(q[tail-1],q[tail],a[i])) tail--;
    while(head<tail && judge(q[head+1],q[head],a[i])) head++;
    q[++tail]=a[i];
   }
    
  while(head<tail && judge(q[tail-1],q[tail],q[head])) tail--;
  while(head<tail && judge(q[head+1],q[head],q[tail])) head++;
  q[tail+1]=q[head]; 
  for(int i=head;i<=tail;i++) b[++n]=get(q[i],q[i+1]);
 }
int main()
 {
 int num,k; scanf("%d",&k);     
 while(k--)
  {scanf("%d",&num);
   for(int i=1;i<=num;i++) scanf("%lf%lf",&b[i].x,&b[i].y);
   b[num+1]=b[1];
   for(int i=1;i<=num;i++) a[++m].p1=b[i],a[m].p2=b[i+1];
  } 
 for(int i=1;i<=m;i++) a[i].th=atan2(a[i].p2.y-a[i].p1.y,a[i].p2.x-a[i].p1.x);
  
 half();
  
 b[n+1]=b[1];
 for(int i=1;i<=n;i++) ans+=b[i]*b[i+1];
 ans=fabs(ans)/2.0;
  
 printf("%.3lf",ans);
 return 0;
 } 


 

posted @ 2018-09-21 20:34  YuXiaoze  阅读(130)  评论(0编辑  收藏  举报