有一个坑点,就是给出的点共线。在加点的时候要判一下就行。剩下的就是半平面交。
有两种情况:瞭望塔的一个端点在半平面的交点上,另一端在山上。
或者一个端点在山上,另一个端点在半平面上。
由于
n
<
=
100
n<=100
n<=100,暴力枚举一下就行了。做半平面的时候我在两边加上了两条竖直边。充当边界。(好像不加也没啥问题)
调试的时候,可以把样例的图画出来,手玩坐标,然后看看自己程序里的坐标算对没有。这样大概可以精准查错。
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
const double inf=1e20;
const int maxn=1000;
int cnt=0,tot=0,n;double x[maxn],y[maxn],ans=inf;
inline int sgn(double x){
if(x>eps) return 1;
if(x<-eps) return -1;
return 0;
}
struct Grid{
double x,y;
Grid(double X=0,double Y=0){x=X,y=Y;}
friend inline Grid operator+(const Grid &a,const Grid &b){return Grid(a.x+b.x,a.y+b.y);}
friend inline Grid operator-(const Grid &a,const Grid &b){return Grid(a.x-b.x,a.y-b.y);}
friend inline Grid operator*(const Grid &a,const double &b){return Grid(a.x*b,a.y*b);}
friend inline Grid operator/(const Grid &a,const double &b){return Grid(a.x/b,a.y/b);}
friend inline double cross(const Grid &a,const Grid &b){return a.x*b.y-a.y*b.x;}
inline void print(){
printf("%.2lf %.2lf\n\n",x,y);
}
}Qp[maxn],p[maxn],q[maxn];typedef Grid Vector,Point;
struct Line{
Point s,t;double Angle;
Line(Point S=Point(),Point T=Point()){s=S,t=T,Angle=atan2(t.y-s.y,t.x-s.x);}
friend inline bool operator<(const Line &a,const Line &b){
double R=a.Angle-b.Angle;
if(sgn(R)!=0) return sgn(R)<0;
return sgn(cross(a.t-a.s,b.t-a.s))<0;
}
friend inline Point Intersection(const Line &a,const Line &b)
{return a.s+(a.t-a.s)*cross(b.t-b.s,a.s-b.s)/cross(a.t-a.s,b.t-b.s);}
friend inline bool Onleft(const Line &a,const Point &b)
{return sgn(cross(a.t-a.s,b-a.s))>0;}
inline void print(int x){
printf("Line[%d]:\n",x);
printf("%.2lf %.2lf\n%.2lf %.2lf\n",s.x,s.y,t.x,t.y);
}
}L[maxn],Ql[maxn];
inline double Half_Intersection(int Head=0,int Tail=0){
sort(L+1,L+cnt+1),Ql[0]=L[1];
for(int i=2;i<=cnt;++i) if(sgn(L[i].Angle-L[i-1].Angle)!=0){
while(Head<Tail&&!Onleft(L[i],Qp[Tail-1])) Tail--;
while(Head<Tail&&!Onleft(L[i],Qp[Head])) Head++;
Ql[++Tail]=L[i],Qp[Tail-1]=Intersection(Ql[Tail],Ql[Tail-1]);
}
while(Head<Tail&&!Onleft(Ql[Head],Qp[Tail-1])) Tail--;
while(Head<Tail&&!Onleft(Ql[Tail],Qp[Head])) Head++;
if(Tail-Head<=1){return inf;}
for(int i=Head;i<=Tail-1;++i){
Point t=Point(Qp[i].x,-1);
for(int j=1;j<n;++j)
if(q[j].x<=Qp[i].x&&Qp[i].x<=q[j+1].x)
ans=min(ans,Qp[i].y-Intersection(Line(Qp[i],t),Line(q[j],q[j+1])).y);
}
for(int j=1;j<=n;++j){
Point t=Point(q[j].x,-1);
for(int i=Head;i<Tail-1;++i)
if(Qp[i].x<=q[j].x&&q[j].x<=Qp[i+1].x)
ans=min(ans,Intersection(Line(Qp[i],Qp[i+1]),Line(q[j],t)).y-q[j].y);
}return ans;
}
int main(){
//freopen("1751.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%lf",&q[i].x);
for(int i=1;i<=n;++i) scanf("%lf",&q[i].y);
q[0].x=q[1].x,q[0].y=inf,q[n+1].x=q[n].x,q[n+1].y=inf;
for(int i=1;i<=n+1;++i)
if(i<2||sgn(cross(q[i]-q[i-2],q[i-1]-q[i-2]))!=0)
L[++cnt]=Line(q[i-1],q[i]);
printf("%.3lf",Half_Intersection());
}