BZOJ2618 CQOI2006 凸多边形
乱搞.jpg
直接看成直线半平面交qwq
挺好写的w
//Love and Freedom. #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define ll long long #define inf 20021225 #define db double #define eps 1e-8 #define N 1010 using namespace std; struct poi { db x,y; poi(){} poi(db _x,db _y){x=_x;y=_y;} }; typedef poi vec; vec operator+(vec a,vec b){return vec(a.x+b.x,a.y+b.y);} vec operator-(vec a,vec b){return vec(a.x-b.x,a.y-b.y);} vec operator*(vec a,db b){return vec(a.x*b,a.y*b);} db cross(vec a,vec b){return a.x*b.y-a.y*b.x;} db angle(vec a){return atan2(a.y,a.x);} struct line { poi p; vec v; db ang; line(){} line(poi p1,poi p2){p = p1; v = p2-p1; ang = angle(v);} }l[N]; void put(poi a) { printf("%lf %lf\n",a.x,a.y); } poi section(line a,line b) { db k = cross(a.v+a.p-b.p,a.p-b.p)/(cross(a.v+a.p-b.p,b.v)+cross(b.v,a.p-b.p)); return b.p+b.v*k; } bool onleft(line a,poi p) { return cross(a.p-p,a.p+a.v-p)>-eps; } int stk[N],hd,tl,n; poi sec[N]; bool cmp(line a,line b) { return a.ang<b.ang || (abs(a.ang-b.ang) < eps && cross(b.v+b.p-a.p,a.v)>eps); } void halfplane() { sort(l+1,l+n+1,cmp); hd = tl = 1; stk[1] = 1; for(int i=1;i<=n;i++) { while(tl>hd && !onleft(l[i],sec[tl-1])) tl--; while(hd<tl && !onleft(l[i],sec[hd])) hd++; stk[++tl] = i; sec[tl-1] = section(l[i],l[stk[tl-1]]); } while(hd<tl && !onleft(l[stk[hd]],sec[tl-1])) tl--; if(hd<tl) sec[tl] = section(l[stk[hd]],l[stk[tl]]); } db calc() { db ans = 0; //for(int i=hd;i<=tl;i++) put(sec[i]); for(int i=hd+1;i<tl;i++) ans+=cross(sec[i]-sec[hd],sec[i+1]-sec[hd]); return ans/2.0; } int main() { int nn,mm; poi poly[N]; scanf("%d",&nn); while(nn--) { scanf("%d",&mm); for(int i=1;i<=mm;i++) scanf("%lf%lf",&poly[i].x,&poly[i].y); for(int i=1;i<mm;i++) l[++n] = line(poly[i],poly[i+1]); l[++n] = line(poly[mm],poly[1]); } halfplane(); printf("%.3lf\n",calc()); return 0; }