题意:求多边形核的面积;
思路:求所有的核心,再求凸包,在求面积。。。没用半平面交的模版。数据水了。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <queue> #include <stack> #include <map> using namespace std; double const INF = 1e20; double const EPS = 1e-8; bool zero(double t){return -EPS<t&&t<EPS;} struct cvector{ double x,y; cvector(){} cvector(double a,double b){x=a,y=b;} }; cvector operator-(cvector a,cvector b){ return cvector(a.x-b.x,a.y-b.y); } cvector operator+(cvector a,cvector b){ return cvector(a.x+b.x,a.y+b.y); } cvector operator*(double a,cvector b){ return cvector(a*b.x,a*b.y); } double operator*(cvector a,cvector b){ return a.x*b.x+a.y*b.y; } double operator^(cvector a,cvector b){ return a.x*b.y-b.x*a.y; } double length(double t){return t<0?-t:t;} double length(cvector t){return sqrt(t*t);} struct cpoint{ double x,y; void get(){scanf("%lf%lf",&x,&y);} int operator<(const cpoint t)const { return x<t.x||(x==t.x&&y<t.y); } }; cvector operator-(cpoint a,cpoint b){ return cvector(a.x-b.x,a.y-b.y); } double dist(cpoint a,cpoint b){ return length(a-b); } struct segline{ cpoint a,b; segline(cpoint x,cpoint y){a=x,b=y;} segline (){} }; cpoint intersection(segline u,segline v){ cpoint ret = u.a; double t = ((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/ ((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x+=(u.b.x-u.a.x)*t; ret.y+=(u.b.y-u.a.y)*t; return ret; } int n; cpoint re[1509]; cpoint tu[1509],tu2[1509]; map<cpoint,int> mp; int oor1() { int cnt = 0; cpoint xx; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(!zero((re[i]-re[i+1])^(re[j]-re[j+1]))) { xx = intersection(segline(re[i],re[i+1]),segline(re[j],re[j+1])); int k; for(k=0;k<n;k++) { if(((re[k]-re[k+1])^(xx-re[k+1]))<-EPS) break; } if(k>=n&&mp.find(xx)==mp.end()) mp[xx] = cnt , tu[cnt++] = xx; } return cnt; } int oor2() { int cnt = 0; cpoint xx; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(!zero((re[i]-re[i+1])^(re[j]-re[j+1]))) { xx = intersection(segline(re[i],re[i+1]),segline(re[j],re[j+1])); int k; for(k=0;k<n;k++) { if(((re[k]-re[k+1])^(xx-re[k+1]))>EPS) break; } if(k>=n&&mp.find(xx)==mp.end()) mp[xx] = cnt , tu[cnt++] = xx; } return cnt; } int x_mult(cpoint a,cpoint b,cpoint c){ return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x); } int cmp(const cpoint a,const cpoint b){ return a.y<b.y||(a.y==b.y&&a.x<b.x); } int granham(cpoint p[],int s,cpoint r[]) { int i,len,top=1; sort(p,p+s,cmp); // for(int i=0;i<s;i++) cout<<p[i].x<<" - "<<p[i].y<<endl; r[0] = p[0],r[1] = p[1];r[2] = p[2]; if(s<3) return s; for(i=2;i<s;i++){ while(top&&x_mult(p[i],r[top],r[top-1])>-EPS) top--; r[++top] = p[i]; } len = top;r[++top] = p[s-2]; for(i=s-3;i>=0;i--){ while(top!=len&&x_mult(p[i],r[top],r[top-1])>-EPS) top--; r[++top] = p[i]; } return top; } double solve() { mp.clear(); int cnt = 0; cpoint xx;xx.x = 0,xx.y = 0; double area=0; for(int i=0;i<n;i++) area+= (re[i]-re[i+1])^(xx-re[i+1]); if(area>0) cnt = oor1(); else cnt = oor2(); if(cnt<3) { return 0; } // for(int i=0;i<cnt;i++) // cout<<tu[i].x<<" "<<tu[i].y<<endl;cout<<endl; int tmp = granham(tu,cnt,tu2); // for(int i=0;i<tmp;i++) // cout<<tu2[i].x<<" "<<tu2[i].y<<endl; if(tmp<3) return 0; double ret = 0; for(int i=0;i<tmp;i++) ret+=(tu2[i]-tu2[i+1])^(xx-tu2[i+1]); return fabs(ret/2); } int main() { freopen("in.txt","r",stdin); int cas; scanf("%d",&cas); while(cas--) { scanf("%d",&n); for(int i=0;i<n;i++) re[i].get(); re[n] = re[0]; printf("%.2lf\n",solve()); } return 0; }