计算几何-BZOJ2618-凸包的交-HPI
This article is made by Jason-Cow.
Welcome to reprint.
But please post the article's address.
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