正解半平面交,%%% PoPoQQQ : http://blog.csdn.net/popoqqq/article/details/39340759
"确定瞭望塔的高度的时候我们选择二分处理 对于二分的每一个值 我们把折线上的端点从左到右枚举 瞭望塔的塔尖到每个端点的连线必须从左到右逆时针顺序 否则就会被遮挡"
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<ctime> #define eps 1e-4 using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } inline int dcmp(double a,double b){ if (fabs(a-b)<1e-5) return 0; if (a<b) return -1; return 1; } struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y) { } friend double Cross(Point p1,Point p2,Point p0){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } }P[305]; int n; double x1,xn; double ans=1e130; inline double rnd(){ return (rand()%1000)/1000.0; } inline double calc(double x){ for (int i=1;i<n;i++) if (dcmp(P[i].x,x)<=0 && dcmp(x,P[i+1].x)<=0) return P[i].y+(P[i+1].y-P[i].y)/(P[i+1].x-P[i].x)*(x-P[i].x); } Point Q[305]; int r; inline int C(Point E){ r=0; for (int i=1;i<=n;i++) { while (r && dcmp(Cross(P[i],Q[r],E),0)>=0) r--; Q[++r]=P[i]; } return r; } inline bool Check(Point E) { for(int i=2;i<=n;i++) if(dcmp(Cross(P[i-1],P[i],E),0)<0) return 0; return 1; } inline double Bin(double x){ double L=0,R=1e11,MID; double y=calc(x); while (R-L>1e-5) if (Check(Point(x,y+(MID=(L+R)/2)))) R=MID; else L=MID; ans=min(ans,(L+R)/2); return (L+R)/2; } inline void SA(){ #define beta .99 #define EPS 1e-5 double nx,sx,now,delta,ret; sx=(x1+xn)/2; now=Bin(sx); for (double T=xn-x1;T>EPS;T*=beta){ nx=sx+T*(rnd()*2-1); if(nx<x1 || nx>xn) continue; ret=Bin(nx); delta=now-ret; if (delta>0 || rnd()<exp(delta/T)) sx=nx,now=ret; } } int main() { #define Case 2 srand(10086); int ix; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); for (int i=1;i<=n;i++) read(ix),P[i].x=ix; for (int i=1;i<=n;i++) read(ix),P[i].y=ix; x1=P[1].x; xn=P[n].x; for (int i=1;i<=Case;i++) SA(); printf("%.3lf\n",ans); return 0; }