[SCOI2015] want to run a small convex

topic

First push wave equation, provided \ (P (X, Y) \) , then we try to write the point \ ((x_i, y_i), (x_ {i + 1}, y_ {i + 1}) \) and \ (p (x, y) \) area of a triangle formed by the cross product is written wave

\[2S=(x_i-x)(y_{i+1}-y)-(x_{i+1}-x)(y_i-y)\]

Vigorously open expression, found \ (2S = (y_ {i } -y_ {i + 1}) x + (x_ {i + 1} -x_i) y + x_iy_ {i + 1} -x_ {i + 1} y_i \)

It is not difficult to find a \ (Ax + By + C \ ) form, must have something to do with a straight line, we set \ (A_i = y_ {i} -y_ {i + 1}, B_i = x_ {i + 1} -x_i, C_i = x_iy_ {i + 1} -x_ {i + 1} y_i \)

We need such \ (\ forall i \ in [ 1, n] \) have \ (A_0x + B_0 + C_0 < A_ix + B_iy + C_i \)

\((A_0-A_i)x+(B_0-B_i)y+(C_0-C_i)<0\)

Hard to find \ ((x, y) \ ) a half-plane in the

The exact stresses when \ (B_0-B_i> 0 \ ) when such \ ((x, y) \ ) in a straight line ) x + (B_0-B_i) y + (C_0-C_i \ ((A_0-A_i) = 0 \) when; downward (B_0-B_i <0 \) \ over time, in line

So we get to this \ (n-\) winding the convex hull constraints and the original (\ n-) \ edges seeking a cross-like half-plane, the answer is a half cross-plane area divided by the area of the convex hull of the original

Code

#include<bits/stdc++.h>
#define re register
const double eps=1e-6;
const int maxn=2e5+5;
int n,h,t,N,tot;
struct Pt{double x,y;}p[maxn];
struct Line{Pt s,t;double det;}L[maxn],q[maxn];
inline int dcmp(double a,double b) {return a+eps>b&&a-eps<b;}
inline Pt operator^(double t,const Pt &A) {return (Pt){t*A.x,t*A.y};}
inline double operator*(const Pt &A,const Pt &B) {return A.x*B.y-A.y*B.x;}
inline Pt operator+(const Pt &A,const Pt &B) {return (Pt){A.x+B.x,A.y+B.y};}
inline Pt operator-(const Pt &A,const Pt &B) {return (Pt){A.x-B.x,A.y-B.y};}
inline int OnRight(const Pt &c,const Line &A) {return (A.t-c)*(A.s-c)>0;}
inline Pt sec(const Line &A,const Line &B) {
    Pt v1=A.t-A.s,v2=B.t-B.s,v3=A.s-B.s;
    double t=(v3*v2)/(v2*v1);
    return A.s+(t^v1);
}
inline int cmp(const Line &A,const Line &B) {
    return dcmp(A.det,B.det)?OnRight(A.s,B):(A.det<B.det);
}
inline void Half() {
    for(re int i=1;i<=N;i++)
        L[i].det=atan2((L[i].t-L[i].s).y,(L[i].t-L[i].s).x);
    std::sort(L+1,L+N+1,cmp);tot=1;h=1,t=0;
    for(re int i=2;i<=N;i++) {
        if(!dcmp(L[i].det,L[i-1].det)) ++tot;
        L[tot]=L[i];
    }
    for(re int i=1;i<=tot;i++) {
        while(h<t&&OnRight(sec(q[t],q[t-1]),L[i])) --t;
        while(h<t&&OnRight(sec(q[h],q[h+1]),L[i])) ++h;
        q[++t]=L[i];
    }
    while(h<t&&OnRight(sec(q[t],q[t-1]),q[h])) --t;
    while(h<t&&OnRight(sec(q[h],q[h+1]),q[t])) ++h;
}
inline void getABC(double &A,double &B,double &C,int i) {
    C=p[i]*p[i+1];A=p[i].y-p[i+1].y,B=p[i+1].x-p[i].x;
}
int main() {
    scanf("%d",&n);double Sum=0,ans=0;
    for(re int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);p[n+1]=p[1];
    for(re int i=1;i<=n;i++) Sum+=fabs((p[i]-p[1])*(p[i+1]-p[1]));
    for(re int i=1;i<=n;i++) L[++N].s=p[i],L[N].t=p[i+1];
    double A1,B1,C1,A,B,C;getABC(A1,B1,C1,1);Line nw;
    for(re int i=2;i<=n;i++) {
        getABC(A,B,C,i);C=C1-C,B=B1-B,A=A1-A;
        if(!dcmp(A,0)) nw.s=(Pt){-C/A,0},nw.t=(Pt){-C/A-B,A};
        else if(!dcmp(B,0)) nw.s=(Pt){0,-C/B},nw.t=(Pt){-B,-C/B+A};
        L[++N]=nw;
    }
    Half();q[t+1]=q[h];int cnt=0;
    for(re int i=h;i<=t;i++) p[++cnt]=sec(q[i],q[i+1]);
    p[cnt+1]=p[1];
    for(re int i=1;i<=cnt;i++) ans+=fabs((p[i]-p[1])*(p[i+1]-p[1]));
    printf("%.4lf\n",ans/Sum);return 0;
}

Guess you like

Origin www.cnblogs.com/asuldb/p/12164691.html