1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| #include <iostream> #include <cmath> #include <algorithm> #include <iomanip> #define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0) using namespace std; typedef long long ll; const double pi=acos(-1); const int SUP=0x800000; const int MAXN=1e6+100; const int INF=0x3f3f3f3f; const double eps=1e-8; struct point{ double x,y; }pt[MAXN]; struct line{ point a,b; }L[MAXN]; int cnt,n,m; int front,tail; int dq[MAXN]; point operator-(point a,point b){ return {a.x-b.x,a.y-b.y}; } double cross(point a,point b){ return a.x*b.y-a.y*b.x; } double area(point a,point b,point c){ return cross(b-a,c-a); } double get_angle(line x){ return atan2(x.b.y-x.a.y,x.b.x-x.a.x); } bool cmp(line a,line b){ double ag1=get_angle(a),ag2=get_angle(b); if(ag1==ag2) return (area(a.a,a.b,b.b)<0); else return ag1<ag2; } point get_J(point p,point u,point q,point v){ point w=p-q; double t=cross(v,w)/cross(u,v); return {p.x+u.x*t,p.y+u.y*t}; } point get_J(line a,line b){ return get_J(a.a,a.b-a.a,b.a,b.b-b.a); } bool onRight(line a,line b,line c){ point x=get_J(b,c); return area(a.a,a.b,x)<=0; } void half(){ sort(L+1,L+1+cnt,cmp); front=1;tail=0; for(int i=1;i<=cnt;i++){ if(i>=2 && get_angle(L[i-1])==get_angle(L[i])) continue; while(tail-front>=1 && onRight(L[i],L[dq[tail-1]],L[dq[tail]])) tail--; while(tail-front>=1 && onRight(L[i],L[dq[front]],L[dq[front+1]])) front++; dq[++tail]=i; } while(tail-front>=1 && onRight(L[dq[front]],L[dq[tail-1]],L[dq[tail]])) tail--; while(tail-front>=1 && onRight(L[dq[tail]],L[dq[front]],L[dq[front+1]])) front++; dq[++tail]=dq[front]; double ans=0; int js=0; for(int i=front;i<tail;i++){ pt[++js]=get_J(L[dq[i]],L[dq[i+1]]); } for(int i=2;i+1<=js;i++){ ans+=area(pt[1],pt[i],pt[i+1]); } cout<<fixed<<setprecision(3)<<ans/2<<'\n'; } int main() { ios; cin>>n; for(int i=1;i<=n;i++){ cin>>m; for(int j=1;j<=m;j++){ cin>>pt[j].x>>pt[j].y; } for(int j=1;j<=m;j++){ if(j!=m) L[++cnt]={pt[j].x,pt[j].y,pt[j+1].x,pt[j+1].y}; else L[++cnt]={pt[j].x,pt[j].y,pt[1].x,pt[1].y}; } } half(); return 0; }
|