真的不是简单的问题啊!
雨水从上方落下。接不到雨的情况:
注意这两种是可以接到雨的
都判断清楚了这题就好做了。
//Memory: 192K //Time: 32MS #include <stdio.h> #include <iostream> #include <math.h> #define EP 1E-6 #define INF 1E100 using namespace std; struct POINT { double x,y; }; struct LINESEG { POINT s,e; }; struct LINE { double a,b,c; POINT A,B; LINE(){}; LINE(POINT _a,POINT _b) { A=_a; B=_b; a=B.y-A.y; b=A.x-B.x; c=B.x*A.y-A.x*B.y; }; }; double multiply(POINT sp,POINT ep,POINT op)//叉积 { return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y); } bool intersect(LINESEG u,LINESEG v)//求线段交点 { return ((max(u.s.x,u.e.x)>=min(v.s.x,v.e.x)) && (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x)) && (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y)) && (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y)) && (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0) && (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0)); } int main() { //freopen("data.txt","r",stdin); //freopen("out.txt","w",stdout); int cas,i; double ans; POINT p[5]; LINESEG l1,l2; scanf("%d",&cas); while(cas--) { ans=0; int my=0; double lx=0; scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y,&p[4].x,&p[4].y); l1.s=p[1];l1.e=p[2]; l2.s=p[3];l2.e=p[4]; if(intersect(l1,l2)) { LINE t[3]; t[1]=LINE(p[1],p[2]); t[2]=LINE(p[3],p[4]); if(fabs(t[1].b/t[1].a-t[2].b/t[2].a)>EP) { double d=t[1].a*t[2].b-t[2].a*t[1].b; p[0].x=(t[2].c*t[1].b-t[1].c*t[2].b)/d; p[0].y=(t[2].a*t[1].c-t[1].a*t[2].c)/d; for(i=1;i<=4;i++) { if(p[i].y>p[0].y) { if(my==0) my=i; else { if(p[i].y<p[my].y) { lx=p[i].x+(t[(my+1)/2].b*p[i].y+t[(my+1)/2].c)/t[(my+1)/2].a; if((multiply(p[i],p[my],p[0])>0 && p[my].x>=p[i].x) || (multiply(p[i],p[my],p[0])<0 && p[my].x<=p[i].x)) lx=0; ans=(p[i].y-p[0].y)*lx/2; } else { lx=p[my].x+(t[(i+1)/2].b*p[my].y+t[(i+1)/2].c)/t[(i+1)/2].a; if((multiply(p[my],p[i],p[0])>0 && p[i].x>=p[my].x) || (multiply(p[my],p[i],p[0])<0 && p[i].x<=p[my].x)) lx=0; ans=(p[my].y-p[0].y)*lx/2; } } } } } ans=fabs(ans); } printf("%.2lf\n",ans); } return 0; }