這道題好傷心啊,我wa了好久,原因是我理解錯了題意。
下面還是先說說題目的解題思路吧:
1、當兩條線段不想交的時候結果是0.00,這裡就排除了平行的情況;
2、當兩條線段有任一條平行於x軸的時候,結果同樣為0.00;
3、當兩條線段相交但是是共線的時候(用平行來判斷),結果同樣為0.00;
4、還有一種情況就是說,如果存在,某一個在上面的木板擋住了下面的木板的時候,那麼同樣結果為0.00;
除了上面的四種情況,然後使用叉積求的交點,然後求到交點之上的可以裝滿水的水平面的y值,使用叉積求面積就可以了。
這道題我wa了很久是因為我認為當兩個木板不想交的時候可以把地面當做一個下面,然後求梯形的面積,結果wa了好久好久,好傷心啊……
下面貼上代碼僅供參考……
#include <cstring>#include <cstdlib>#include <cstdio>#include <iostream>#include <cmath>using namespace std;const double eps=1e-8;int dblcmp(double x){ if(fabs(x)<eps) return 0; return x>0.0?1:-1;}typedef struct POINT{ double x,y; POINT(){} POINT(double tx,double ty) { x=tx,y=ty; }}Point;double dotmult(Point a,Point b,Point c){ return (c.x-a.x)*(b.x-c.x)+(c.y-a.y)*(b.y-c.y);}double xmult(Point p1,Point p2,Point p0){ return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);}int isCross(Point a,Point b,Point c,Point d)//規範相交{ int t1=dblcmp(xmult(c,a,b)); int t2=dblcmp(xmult(d,a,b)); int t3=dblcmp(xmult(a,c,d)); int t4=dblcmp(xmult(b,c,d)); if(t1*t2<0&&t3*t4<0) return 1; return 0;}int isCross2(Point a,Point b,Point c,Point d)//非規範相交{ int t1=dblcmp(xmult(c,a,b)); int t2=dblcmp(xmult(d,a,b)); int t3=dblcmp(xmult(a,c,d)); int t4=dblcmp(xmult(b,c,d)); if(t1*t2<0&&t3*t4<0) return 1; if(t1==0&&dblcmp(dotmult(a,b,c))>=0) return 1; if(t2==0&&dblcmp(dotmult(a,b,d))>=0) return 1; if(t3==0&&dblcmp(dotmult(c,d,a))>=0) return 1; if(t4==0&&dblcmp(dotmult(c,d,b))>=0) return 1; return 0;}Point getCrossPoint(Point a,Point b,double yy){ double dx=b.x-a.x; double dy=b.y-a.y; if(dblcmp(dx)==0) { return Point(a.x,yy); } else { double k=dy/dx; if(dblcmp(k)==0) { return Point(max(a.x,b.x),yy); } else { return Point((yy-a.y)/k+a.x,yy); } }}int isUpon(Point ,Point ,Point ,Point);double solveTringle(Point p1,Point p2,Point p3,Point p4){ if(dblcmp((p2.x-p1.x)*(p4.y-p3.y)-(p2.y-p1.y)*(p4.x-p3.x))==0) return 0.0; if(isUpon(p1,p2,p3,p4)) return 0.00; double t1=xmult(p1,p3,p4); double t2=xmult(p2,p3,p4); Point p0; p0.x=(t1*p2.x-t2*p1.x)/(t1-t2); p0.y=(t1*p2.y-t2*p1.y)/(t1-t2); double yy1=max(p1.y,p2.y); double yy2=max(p3.y,p4.y); double yy; if(dblcmp(yy1-p0.y)==0||dblcmp(yy2-p0.y)==0) return 0.00; if(dblcmp(yy1-yy2)>=0) { yy=yy2; Point p11=getCrossPoint(p1,p2,yy); Point p22=getCrossPoint(p3,p4,yy); return abs(xmult(p11,p22,p0))/2.0; } else { yy=yy1; Point p11=getCrossPoint(p1,p2,yy); Point p22=getCrossPoint(p3,p4,yy); return abs(xmult(p11,p22,p0))/2.0; }}void mySwap(Point &a,Point &b){ Point t; t.x=a.x,t.y=a.y; a.x=b.x,a.y=b.y; b.x=t.x,b.y=t.y;}int isUpon(Point p1,Point p2,Point p3,Point p4)//判斷是否遮擋……{ if(isCross2(p1,p2,p4,Point(p4.x,10000.0))) return 1; return 0;}int main(){ // freopen("poj2826in.txt","r",stdin); // freopen("myout.txt","w",stdout); int t; double ans; Point p1,p2,p3,p4; scanf("%d",&t); while(t--) { scanf("%lf %lf %lf %lf",&p1.x,&p1.y,&p2.x,&p2.y); scanf("%lf %lf %lf %lf",&p3.x,&p3.y,&p4.x,&p4.y); if(dblcmp(p1.y-p2.y)>0) mySwap(p1,p2); if(dblcmp(p3.y-p4.y)>0) mySwap(p3,p4); if(dblcmp(p2.y-p4.y)<0) { mySwap(p1,p3); mySwap(p2,p4); } if(dblcmp(p2.y-p1.y)==0) ans=0.00; else if(dblcmp(p4.y-p3.y)==0) ans=0.00; else if(isCross2(p1,p2,p3,p4)) ans=solveTringle(p1,p2,p3,p4); else ans=0.00; printf("%.2f\n",ans); } return 0;}