bzoj2618凸多邊形面積交
阿新 • • 發佈:2019-02-12
(⊙v⊙)嗯,幾何大水題
題意是要求n個凸多邊形(逆時針給定點)的面積交,資料很弱。
把每個多邊形拆成直線,然後掃一遍做半平面交,最後統計答案就可以了:
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> #include<cmath> #define eps 1e-10 using namespace std; const int maxn=505; int dcmp(double x) { if(fabs(x)<eps)return 0; else return x<0?-1:1; } struct point { double x,y; point(){} point(double _x,double _y) { x=_x; y=_y; } point operator +(const point &b) { return point(x+b.x,y+b.y); } point operator -(const point &b) { return point(x-b.x,y-b.y); } point operator *(const double &b) { return point(x*b,y*b); } }; struct line { point p,v; double ang; line(){} line(point _p,point _v) { p=_p; v=_v; ang=atan2(v.y,v.x); } bool operator <(const line &l)const { return ang<l.ang; } }; double cross(point a,point b) { return a.x*b.y-a.y*b.x; } double dot(point a,point b) { return a.x*b.x+a.y*b.y; } bool onleft(line l,point p) { return dcmp(cross(l.v,p-l.p))>0; } point getsec(point p1,point v1,point p2,point v2) { double x=cross(p2-p1,v2)/cross(v1,v2); return v1*x+p1; } void hp(line *L,int n) { sort(L+1,L+n+1); int first,last; point p[maxn]; line q[maxn]; q[first=last=0]=L[1]; for(int i=2;i<=n;i++) { while(first<last&&!onleft(L[i],p[last-1]))last--; while(first<last&&!onleft(L[i],p[first]))first++; q[++last]=L[i]; if(dcmp(cross(q[last].v,q[last-1].v))==0) { last--; if(!onleft(L[i],p[last-1]))q[last]=L[i]; } if(first<last)p[last-1]=getsec(q[last].p,q[last].v,q[last-1].p,q[last-1].v); } while(first<last&&!onleft(q[first],p[last-1]))last--; if(last-first<=1) { printf("0.000\n"); return ; } p[last]=getsec(q[last].p,q[last].v,q[first].p,q[first].v); double ans=0; for(int i=first;i<last;i++)ans+=cross(p[i]-p[first],p[i+1]-p[first]); ans=0.5*fabs(ans); printf("%.3f\n",ans); //for(int i=first;i<=last;i++)printf("%lf %lf\n",p[i].x,p[i].y); } point p[maxn]; line l[maxn]; int cnt; int main() { int n; cnt=0; scanf("%d",&n); for(int i=1;i<=n;i++) { int m; scanf("%d",&m); for(int j=1;j<=m;j++)scanf("%lf%lf",&p[j].x,&p[j].y); p[m+1]=p[1]; for(int j=1;j<=m;j++) { l[++cnt]=line(p[j],p[j+1]-p[j]); } } hp(l,cnt); return 0; }