http://www.lydsy.com/JudgeOnline/problem.php?id=4445
这次是重做,但发现自己被读入优化坑了,不造为什么,反正改了就过了,坑爹~~~double坑爹
scoi2015day1 攻克完成(虽然是看了题解的很水攻克~~)
之前写过思路了,这里不再说了~~~
转成不等关系跑半平面交
(吐槽:还是推不等式ax+by+c<0的时候很坑,手动推起来确实很恶心QAQ)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
#define eps 1e-10
using namespace std;
const int maxn=200000+20;
int dcmp(double x)
{
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
struct point
{
double x,y;
point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}
point operator +(const point &b)
{
return point(x+b.x,y+b.y);
}
point operator -(const point &b)
{
return point(x-b.x,y-b.y);
}
point operator *(const double &b)
{
return point(x*b,y*b);
}
};
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
struct line
{
point p,v;
double ang;
line(){}
line (point _p,point _v)
{
p=_p;
v=_v;
ang=atan2(v.y,v.x);
}
bool operator <(const line&l)const
{
return ang<l.ang;
}
}l[maxn];
bool onleft(point p,line l)
{
return dcmp(cross(l.v,p-l.p))>0;
}
double x[maxn],y[maxn];
int cnt;
int read()
{
int res=0;
char c=getchar();
for(;c<'0'||c>'9';c=getchar());
for(;c>='0'&&c<='9';c=getchar())res=res*10+c-'0';
return res;
}
point getsec(point p1,point v1,point p2,point v2)
{
double x=cross(p2-p1,v2)/cross(v1,v2);
return v1*x+p1;
}
point p[maxn];
line q[maxn];
double hp(line *L,int n)
{
sort(L+1,L+n+1);
int first,last;
q[first=last=0]=L[1];
for(int i=2;i<=n;i++)
{
while(first<last&&!onleft(p[last-1],L[i]))last--;
while(first<last&&!onleft(p[first],L[i]))first++;
q[++last]=L[i];
if(dcmp(cross(q[last].v,q[last-1].v))==0)
{
last--;
if(!onleft(p[last-1],L[i]))q[last]=L[i];
}
if(first<last)p[last-1]=getsec(q[last].p,q[last].v,q[last-1].p,q[last-1].v);
}
while(first<last&&!onleft(p[last-1],q[first]))last--;
if(last-first<=1)return 0;
p[last]=getsec(q[last].p,q[last].v,q[first].p,q[first].v);
double ans=0;
for(int i=first;i<last;i++)ans+=cross(p[i]-p[first],p[i+1]-p[first]);
ans=0.5*fabs(ans);
return ans;
}
int n;
void init()
{
double x1=x[1],y1=y[1];
double x2=x[2],y2=y[2];
cnt=0;
for(int i=2;i<=n;i++)
{
double x3=x[i],y3=y[i];
double x4=x[i+1],y4=y[i+1];
double a,b,c;
//手推(y1+y4-y2-y3)x+(x2+x3-x1-x4)y+(x1y2-x2y1+x4y3-x3y4)<0
a=y1+y4-y2-y3;
b=x2+x3-x1-x4;
c=x1*y2-x2*y1+x4*y3-x3*y4;
//(-b,a) ax+by+c<0
++cnt;
point v,p;
v=point(-b,a);
if(dcmp(b)!=0)p=point(0,-c/b);
else p=point(-c/a,0);
l[cnt]=line(p,v);
}
++cnt;
l[cnt]=line(point(x[1],y[1]),point(x2-x1,y2-y1));
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&x[i],&y[i]);
}
x[n+1]=x[1];
y[n+1]=y[1];
double ans1=0;
for(int i=1;i<n;i++)
{
ans1+=cross(point(x[i]-x[1],y[i]-y[1]),point(x[i+1]-x[1],y[i+1]-y[1]));
}
ans1=0.5*fabs(ans1);
init();
double ans2=hp(l,cnt);
printf("%.4f\n",ans2/ans1);
return 0;
}