把每个三角形的面积用叉积表示,每个三角形和 0 , 1 , p 0,1,p 0,1,p组成的三角形组合可以列出 n − 1 n-1 n−1个不等式,然后把不等式转成直线做半平面交即可
Code:
#include<bits/stdc++.h>
#define db long double
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
const int N=2e5+5;
struct point{
db x,y;
point(){}
point(db _x,db _y):x(_x),y(_y){}
friend inline point operator + (const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
friend inline point operator - (const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
friend inline point operator * (const point &a,const db &b){return point(a.x*b,a.y*b);}
friend inline db operator * (const point &a,const point &b){return a.x*b.y-a.y*b.x;}
}p[N];
struct line{
point x,y;
db ang;
line(){}
line(point _x,point _y):x(_x),y(_y),ang(atan2(y.y,y.x)){}
}l[N];
inline bool lft(line a,point b){return a.y*(b-a.x)>=0;}
inline bool cmp(line a,line b){
if(fabs(a.ang-b.ang)==0) return lft(a,b.x);
return a.ang<b.ang;
}
inline point itse(line a,line b){
point bs=a.x-b.x;
db tmp=(b.y*bs)/(a.y*b.y);
return a.x+a.y*tmp;
}
int q[N];
int n,tot;
db ans=0,sum=0;
inline void hp(){
int hd=1,ta=2;
sort(l+1,l+tot+1,cmp);
int pos=1;
for(int i=2;i<=tot;i++) if(fabs(l[i].ang-l[pos].ang)>0) l[++pos]=l[i];
tot=pos;
q[1]=1,q[2]=2;
for(int i=3;i<=tot;i++){
while(hd<ta && lft(l[i],itse(l[q[ta-1]],l[q[ta]]))) --ta;
while(hd<ta && lft(l[i],itse(l[q[hd+1]],l[q[hd]]))) ++hd;
q[++ta]=i;
}
while(hd<ta && lft(l[q[hd]],itse(l[q[ta-1]],l[q[ta]]))) --ta;
for(int i=hd;i<ta;i++) p[i]=itse(l[q[i]],l[q[i+1]]);
p[ta]=itse(l[q[ta]],l[q[hd]]);
for(int i=hd;i<ta;i++) ans+=p[i]*(p[i+1]-p[i]);
ans+=p[ta]*(p[hd]-p[ta]);
}
int main(){
n=read();
for(int i=0;i<n;i++) p[i].x=read(),p[i].y=read();
p[n]=p[0];
for(int i=0;i<n;i++) l[++tot]=line(p[i+1],p[i]-p[i+1]),sum+=p[i]*(p[i+1]-p[i]);
for(int i=1;i<n;i++){
db a=p[i+1].x-p[i].x-p[1].x+p[0].x;
db b=p[i+1].y-p[i].y-p[1].y+p[0].y;
db c=-(p[i]*(p[i+1]-p[i]))+p[0]*(p[1]-p[0]);
if(fabs(a)>0) l[++tot]=line(point(0,c/a),point(-a,-b));
else if(fabs(b)>0) l[++tot]=line(point(-c/b,0),point(0,-b));
}
hp();
printf("%.4lf",(double)fabs(ans/sum));
return 0;
}