【BZOJ 4445】[Scoi2015]小凸想跑步 半平面交

来源:互联网 发布:疯狂的美工助手破解版 编辑:程序博客网 时间:2024/05/01 17:26
半平面交解不等式方程组
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>#define eps 1e-10#define maxn 500021using namespace std;int n,cnt,tot;double all;struct P{double x,y;void init(){scanf("%lf%lf",&x,&y);}P(double a=0,double b=0):x(a),y(b){}}p[maxn];typedef P vec;double operator*(P a,P b){return a.x*b.y-a.y*b.x;}vec operator-(P a,P b){return vec(a.x-b.x,a.y-b.y);}P operator+(P a,vec b){return P(a.x+b.x,a.y+b.y);}vec operator/(vec a,double t){return vec(a.x/t,a.y/t);}vec operator*(vec a,double t){return vec(a.x*t,a.y*t);}bool dcmp(double a,double b){return fabs(a-b)<=eps;}struct Line{P a;vec b;double slop;bool operator<(const Line& y)const{if(fabs(slop-y.slop)>eps)return slop<y.slop;return b*(y.a-a)<0;}}l[maxn],q[maxn];void build(){scanf("%d",&n);p[1].init(),p[2].init();double a,b,c,x,y;p[n+1]=p[1];for(int j,i=3;i<=n+1;i++){if(i<=n)p[i].init();j=i-1;a=p[1].y-p[2].y-p[j].y+p[i].y;b=p[2].x-p[1].x-p[i].x+p[j].x; c=(p[2].x*p[1].y-p[1].x*p[2].y+p[j].x*p[i].y-p[i].x*p[j].y)*-1;l[++cnt].a= fabs(a)>eps ? P(-c/a,0) : P(0,-c/b);l[cnt].b=vec(-b,a);}for(int i=1;i<=n;i++)all+=p[i]*p[i+1];for(int i=1;i<=n;i++){l[++cnt].a=p[i];l[cnt].b=p[i+1]-p[i];}for(int i=1;i<=cnt;i++)l[i].slop=atan2(l[i].b.y,l[i].b.x);sort(l+1,l+1+cnt);for(int i=1;i<=cnt;i++){if(!dcmp(l[i].slop,l[i-1].slop)||i==1)l[++tot]=l[i];}cnt=tot;}P Q(Line aa,Line bb){P A=aa.a,B=bb.a;vec a=aa.b,b=bb.b,c=A-B;double k=(b*c)/(a*b);return A+a*k;}bool judge(Line a,Line b,Line c){P x=Q(a,b);return (x-c.a)*c.b>0;}void solve(){q[1]=l[1];int L=1,R=1;for(int i=2;i<=cnt;i++){while(L<R&&judge(q[R-1],q[R],l[i]))R--;while(L<R&&judge(q[L],q[L+1],l[i]))L++;q[++R]=l[i];}while(L<R&&judge(q[R-1],q[R],q[L]))R--;q[R+1]=q[L];tot=0;for(int i=L;i<=R;i++){p[++tot]=Q(q[i],q[i+1]);}p[tot+1]=p[1];}int main(){build();solve();double ans=0;for(int i=1;i<=tot;i++)ans+=p[i]*p[i+1];if(tot<3){puts("0.0000");return 0;}all=fabs(all),ans=fabs(ans);ans=ans/all;printf("%.4lf",ans);return 0;}

0 0