POJ 2826 An Easy Problem?!

题意:在平面上给两块板,求竖直落下的雨水能接多少

题解:巨恶心。。。有几个要特别注意的地方:

1.板平行-->0.00

2.一板盖住另一板-->0.00;

3.无交点-->0.00;'

4.能接水的模型:x型 、 v型、 Y型;

解决方法:

1.求的两线段的直线方程后直接判断a==0?

2.先求得有无交点,然后看交点的y,然后把两个最高的y找出来,这两个y不能小于交点y(就是交点必须是第三大的y)

然后判断 有第二大的y的那个线段对应x ,求另一条线段在x时的纵坐标,如果该值大于y且小于最大y,则为盖住

3.求接水量:找到矮点的木板,看它最大y对应另一木板(横切过去)的x值是多少,然后求(x1,y) (x2,y) (x0,y0) 构成的面积即可。

其中x1 x2 是 纵坐标为y时,两木板的x值,x0,y0为交点坐标。

代码:

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <cmath>
  8 using namespace std;
  9 const double INF  = 1E200;
 10 const double eps = 1E-8;
 11 struct POINT{
 12         double x,y;
 13         POINT( double a = 0,double b = 0 )  { x = a; y = b; }
 14 };
 15 POINT p[100+5];
 16 struct LINE           // 直线的解析方程 a*x+b*y+c=0  为统一表示,约定 a >= 0
 17 {
 18    double a;
 19    double b;
 20    double c;
 21    LINE(double d1=1, double d2=-1, double d3=0) {a=d1; b=d2; c=d3;}
 22 };
 23 struct LINESEG{
 24         POINT e;
 25         POINT s;
 26         LINESEG( POINT x,POINT y ) { e = x; s = y; }
 27         LINESEG(){}
 28 };
 29 
 30 
 31 double dist(POINT p1,POINT p2)
 32 {
 33  return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
 34 }
 35 double multiply(POINT sp,POINT ep,POINT op)
 36 {
 37  return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
 38 }
 39 bool intersect(LINESEG u,LINESEG v)
 40 {
 41  return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&&                     //排斥实验
 42    (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
 43    (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
 44    (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
 45    (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&&         //跨立实验
 46    (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));
 47 }
 48  //根据已知两点坐标,求过这两点的直线解析方程: a*x+b*y+c = 0  (a >= 0)
 49 LINE makeline(POINT p1,POINT p2)
 50 {
 51  LINE tl;
 52  int sign = 1;
 53  tl.a=p2.y-p1.y;
 54  if(tl.a<0)
 55  {
 56   sign = -1;
 57   tl.a=sign*tl.a;
 58  }
 59  tl.b=sign*(p1.x-p2.x);
 60  tl.c=sign*(p1.y*p2.x-p1.x*p2.y);
 61  return tl;
 62 }
 63 bool lineintersect(LINE l1,LINE l2,POINT &p) // 是 L1,L2
 64 {
 65  double d=l1.a*l2.b-l2.a*l1.b;
 66  if(abs(d)<eps) // 不相交
 67   return false;
 68  p.x = (l2.c*l1.b-l1.c*l2.b)/d;
 69  p.y = (l2.a*l1.c-l1.a*l2.c)/d;
 70  return true;
 71 }
 72 int main()
 73 {
 74        // freopen("out.txt","w",stdout);
 75        int test;
 76        cin>>test;
 77         while(test--)
 78         {
 79                 POINT p[5];
 80                 int x[5],y[5];
 81                 int flag = 0;
 82                 int idx1,idy1,idx2,idy2;
 83                 for(int i = 1;i <= 4; i++) cin>>x[i]>>y[i];
 84                 LINESEG s1,s2;
 85                 s1.e.x = x[1];s1.e.y = y[1];
 86                 s1.s.x = x[2];s1.s.y = y[2];
 87                 s2.e.x = x[3];s2.e.y = y[3];
 88                 s2.s.x = x[4];s2.s.y = y[4];
 89                 if(!intersect(s1,s2)){puts("0.00");continue;}
 90                 LINE l1 = makeline(s1.e,s1.s);
 91                 LINE l2 = makeline(s2.e,s2.s);
 92                 if(l1.a == 0 || l2.a == 0){ puts("0.00");continue;}
 93                 lineintersect(l1,l2,p[0]);
 94                 idy1 = 1;
 95                 if(y[2]>y[1]) idy1 = 2;
 96                 idy2 = 3;
 97                 if(y[4]>y[3]) idy2 = 4;
 98                 if(y[idy1]>=y[idy2]) { p[1].x = x[idy1];p[1].y = y[idy1];p[2].x = x[idy2]; p[2].y = y[idy2]; }
 99                 else { p[1].x = x[idy2]; p[1].y = y[idy2]; p[2].x = x[idy1];p[2].y = y[idy1]; }
100                  l1 = makeline(p[0],p[1]);
101                  l2 = makeline(p[0],p[2]);
102                 if(l1.b!=0){
103                 double yt = (-l1.c - l1.a*p[2].x)/l1.b;
104                 if(yt - p[2].y>eps&&yt - p[1].y<eps&&yt-p[0].y>eps){ puts("0.00");continue;}
105                 }
106                 double xt = (- l1.c - l1.b*p[2].y)/l1.a;
107                 POINT k;
108                 k.x = xt;
109                 k.y = p[2].y;
110                 double s = multiply(p[2],p[0],k);
111                 if(s<eps) s = -s;
112                 printf("%.2f\n",s/2+eps);
113         }
114 }
View Code

 

posted on 2015-08-22 22:17  小松song  阅读(94)  评论(0)    收藏  举报

导航