直线相交+区间覆盖——poj2074
感觉计算几何好多细节啊
这题的细节:障碍物在马路下面,在房子上面,都不用算
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define N 205 typedef double db; const db eps=1e-8; const db pi=acos(-1); int sign(db k){if (k>eps) return 1; else if (k<-eps) return -1; return 0;} int cmp(db k1,db k2){return sign(k1-k2);} struct point{ db x,y; point(){} point(db x,db y):x(x),y(y){} point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};} point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};} point operator * (db k1) const{return (point){x*k1,y*k1};} point operator / (db k1) const{return (point){x/k1,y/k1};} }; db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;} int intersect(db l1,db r1,db l2,db r2){ if (l1>r1) swap(l1,r1); if (l2>r2) swap(l2,r2); return cmp(r1,l2)!=-1&&cmp(r2,l1)!=-1; } int checkSS(point k1,point k2,point k3,point k4){ return sign(cross(k1-k3,k2-k3))*sign(cross(k1-k4,k2-k4))<=0; } point getLL(point k1,point k2,point k3,point k4){ db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3); return (k1*w2+k2*w1)/(w1+w2); } int n; point k1,k2,k3,k4,k5,k6,k7;//k1,k2:房子 k3,k4:大街 k5,k6:障碍物 struct Seg{ db l,r; }seg[N]; int comp(Seg a,Seg b){return a.l<b.l;} int main(){ while(cin>>k1.x && sign(k1.x)){ cin>>k2.x>>k1.y;k2.y=k1.y; cin>>k3.x>>k4.x>>k3.y;k4.y=k3.y; cin>>n; for(int i=1;i<=n;i++){ seg[i].l=seg[i].r=0; scanf("%lf%lf%lf",&k5.x,&k6.x,&k5.y); k6.y=k5.y; if(k5.y>=k1.y || k5.y<=k3.y)continue; k7=getLL(k1,k6,k3,k4); seg[i].r=k7.x; k7=getLL(k2,k5,k3,k4); seg[i].l=k7.x; } sort(seg+1,seg+1+n,comp); for(int i=1;i<=n;i++){ if(seg[i].l<k3.x)seg[i].l=k3.x; if(seg[i].r<k3.x)seg[i].r=k3.x; if(seg[i].l>k4.x)seg[i].l=k4.x; if(seg[i].r>k4.x)seg[i].r=k4.x; } db Max=-1e18,nowR=0; for(int i=1;i<=n;i++){ if(seg[i].l>nowR) Max=max(Max,seg[i].l-nowR); nowR=max(nowR,seg[i].r); } Max=max(Max,k4.x-seg[n].r); if(sign(Max)<=0)puts("No View"); else printf("%.2f\n",Max); } }