计算几何BZOJ2618凸包的交HPI

This article is made by Jason-Cow.
Welcome to reprint.
But please post the article's address.

bzoj2618

1A,看懂了题目就是读入的复杂度

把每个凸包看成m个约束条件

一起读入然后做一次HPI

O((nm)log(nm)) (nm<=500,时间完全可以承受)

/**************************************************************
    Problem: 2618
    User: Jaosn_liu
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1332 kb
****************************************************************/

ACcode

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 #include <vector>
  7 #include <cmath>
  8 #include <queue>
  9 #include <map>
 10 #include <set>
 11 using namespace std;
 12 #define sqr(x) ((x)*(x))
 13 #define RG register
 14 #define op operator
 15 #define IL inline
 16 typedef double db;
 17 typedef bool bl;
 18 const db pi=acos(-1.0),eps=1e-10;
 19 struct D{
 20   db x,y;
 21   D(db x=0.0,db y=0.0):x(x),y(y){}
 22 };
 23 typedef D V;
 24 bl operator<(D A,D B){return A.x<B.x||(A.x==B.x&&A.y<B.y);}
 25 V operator+(V A,V B){return V(A.x+B.x,A.y+B.y);}
 26 V operator-(V A,V B){return V(A.x-B.x,A.y-B.y);}
 27 V operator*(V A,db N){return V(A.x*N,A.y*N);}
 28 V operator/(V A,db N){return V(A.x/N,A.y/N);}
 29 
 30 db Ang(db x){return(x*180.0/pi);}
 31 db Rad(db x){return(x*pi/180.0);}
 32 V Rotate(V A,db a){return V(A.x*cos(a)-A.y*sin(a),A.x*sin(a)+A.y*cos(a));}
 33 db Dis(D A,D B){return sqrt(sqr(A.x-B.x)+sqr(A.y-B.y));}
 34 db Cross(V A,V B){return A.x*B.y-A.y*B.x;}
 35 
 36 db Area(D*R,int n){
 37   db S=0.0;
 38   for(int i=1;i<n;i++)S+=Cross(R[i]-R[1],R[i+1]-R[1]);
 39   return S/2;
 40 }
 41 
 42 db Length(D*R,int n){
 43   db C=0.0;
 44   for(int i=2;i<=n;i++)C+=Dis(R[i],R[i-1]);
 45   return C+Dis(R[n],R[1]);
 46 }
 47 
 48 struct L{
 49   D P,v;
 50   db a;
 51   L(){}
 52   L(D P,V v):P(P),v(v){a=atan2(v.y,v.x);}
 53   bool operator<(const L x)const{return a<x.a;}
 54 };
 55 
 56 D Intersect(L a,L b){
 57   V u=a.P-b.P;
 58   return a.P+a.v*(Cross(b.v,u)/Cross(a.v,b.v));
 59 }
 60 
 61 bool Left(L l,D A){
 62   return Cross(l.v,A-l.P)>0;
 63 }
 64 
 65 int HPI(L*l,int n,D*ans){
 66   int head,tail,m=0;
 67   D*P=new D[n];L*q=new L[n];
 68   sort(l+1,l+n+1),q[head=tail=0]=l[1];
 69   for(int i=2;i<=n;i++){
 70     while(head<tail && !Left(l[i],P[tail-1]))tail--;
 71     while(head<tail && !Left(l[i],P[head]))  head++;
 72     q[++tail]=l[i];
 73     if(fabs(Cross(q[tail].v,q[tail-1].v))<eps){
 74       tail--;
 75       if(Left(q[tail],l[i].P))q[tail]=l[i];
 76     }
 77     if(head<tail)P[tail-1]=Intersect(q[tail-1],q[tail]);
 78   }
 79   while(head<tail && !Left(q[head],P[tail-1]))tail--;
 80   if(tail-head<=1)return 0;
 81   P[tail]=Intersect(q[tail],q[head]);
 82   for(int i=head;i<=tail;i++)ans[++m]=P[i];
 83   return m;
 84 }
 85 
 86 const int maxn=500+10;
 87 int n,m,cnt;
 88 L l[maxn];
 89 D A[maxn],Temp,Last,Now;
 90 db a,b;
 91 
 92 int main(){
 93     scanf("%d",&n);
 94     while(n--){
 95         scanf("%d",&m);
 96         scanf("%lf%lf",&a,&b);
 97         Last=D(a,b);
 98         Temp=Last;
 99         for(int i=2;i<=m;i++){
100             scanf("%lf%lf",&a,&b);
101             Now=D(a,b);
102             l[++cnt]=L(Last,Now-Last);
103             Last=Now;
104         }
105         l[++cnt]=L(Now,Temp-Now);
106     }
107     printf("%.3lf\n",Area(A,HPI(l,cnt,A)));
108     return 0;
109 }
~~Jason_liu O(∩_∩)O
原文地址:https://www.cnblogs.com/JasonCow/p/6622484.html