【半平面交】bzoj1038 [ZJOI2008]瞭望塔
http://m.blog.csdn.net/blog/qpswwww/44105605
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define EPS 0.0000001 #define N 311 typedef double db; const db PI=acos(-1.0); struct Point{db x,y;}; typedef Point Vector; Vector operator - (const Point &a,const Point &b){return (Vector){a.x-b.x,a.y-b.y};} Vector operator * (const Vector &a,const db &k){return (Vector){a.x*k,a.y*k};} Vector operator + (const Vector &a,const Vector &b){return (Vector){a.x+b.x,a.y+b.y};} db Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;} struct Line { Point p; Vector v; db ang; Line(){} Line(const Point &a,const Point &b) { v=b-a; p=a; ang=atan2(v.y,v.x); if(ang<0) ang+=2.0*PI; } }; bool operator < (const Line &a,const Line &b){return a.ang<b.ang;} bool OnLeft(Line l,Point a){return Cross(l.v,a-l.p)>0;} Point GetJiaodian(Line a,Line b){return a.p+a.v*(Cross(b.v,a.p-b.p)/Cross(a.v,b.v));} int n; Point ps[N]; Line q[N]; int head=1,tail=1; Line ls[N]; void BPMJ() { sort(ls+1,ls+n+1); q[1]=ls[1]; for(int i=2;i<=n;++i) { while(head<tail&&(!OnLeft(ls[i],ps[tail-1]))) --tail; while(head<tail&&(!OnLeft(ls[i],ps[head]))) ++head; q[++tail]=ls[i]; if(fabs(Cross(q[tail].v,q[tail-1].v))<EPS) { --tail; if(OnLeft(q[tail],ls[i].p)) q[tail]=ls[i]; } if(head<tail) ps[tail-1]=GetJiaodian(q[tail-1],q[tail]); } while(head<tail&&(!OnLeft(q[head],ps[tail-1]))) --tail; ps[tail]=GetJiaodian(q[tail],q[head]); } int nn; Point a[N]; db ans=999999999999999999.0; #define INF 10000000000.0 int main() { // freopen("bzoj1038.in","r",stdin); scanf("%d",&nn); for(int i=1;i<=nn;++i) scanf("%lf",&a[i].x); for(int i=1;i<=nn;++i) scanf("%lf",&a[i].y); for(int i=1;i<nn;++i) ls[++n]=Line(a[i],a[i+1]); ls[++n]=Line((Point){INF,INF},(Point){-INF,INF}); ls[++n]=Line((Point){-INF,INF},(Point){-INF,-INF}); ls[++n]=Line((Point){-INF,-INF},(Point){INF,-INF}); ls[++n]=Line((Point){INF,-INF},(Point){INF,INF}); BPMJ(); for(int i=head;i<=tail;++i) for(int j=1;j<nn;++j) if(ps[i].x>=a[j].x&&ps[i].x<=a[j+1].x) { db ty=a[j].y+(ps[i].x-a[j].x)/(a[j+1].x-a[j].x)*(a[j+1].y-a[j].y); ans=min(ans,ps[i].y-ty); break; } for(int i=1;i<=nn;++i) { for(int j=head;j<tail;++j) if(a[i].x>=ps[j].x&&a[i].x<=ps[j+1].x) { db ty=ps[j].y+(a[i].x-ps[j].x)/(ps[j+1].x-ps[j].x)*(ps[j+1].y-ps[j].y); ans=min(ans,ty-a[i].y); } if(a[i].x>=ps[tail].x&&a[i].x<=ps[head].x) { db ty=ps[tail].y+(a[i].x-ps[tail].x)/(ps[head].x-ps[tail].x)*(ps[head].y-ps[tail].y); ans=min(ans,ty-a[i].y); } } printf("%.3lf\n",ans); return 0; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/