poj2826An Easy Problem?!

链接

繁琐细节题。

1、线段无交点时,ans=0;

2、如图 假设过p3.y的水平线与p1p2相交

poj2826An Easy Problem?!

因为雨是垂直下落的,左图的情况是无法收集到雨水的,而这种情况有一种简便的判定方式 cross(p1-p2,p3-p4)与cross((p1+(0,1))-p1,p1,p3)同号

对于右边的,阴影部分即为ans,求出水平交点tp,p1p2与p3p4的交点pp,ans = fabs(cross(tp-pp,p3-pp))/2;

  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 #include<vector>

  7 #include<cmath>

  8 #include<queue>

  9 #include<set>

 10 using namespace std;

 11 #define N 100000

 12 #define LL long long

 13 #define INF 0xfffffff

 14 const double eps = 1e-8;

 15 const double pi = acos(-1.0);

 16 const double inf = ~0u>>2;

 17 struct point

 18 {

 19     double x,y;

 20     point(double x=0,double y=0):x(x),y(y) {}

 21 } p[10];

 22 typedef point pointt;

 23 pointt operator -(point a,point b)

 24 {

 25     return pointt(a.x-b.x,a.y-b.y);

 26 }

 27 int dcmp(double x)

 28 {

 29     if(fabs(x)<eps) return 0;

 30     return x<0?-1:1;

 31 }

 32 double cross(point a,point b)

 33 {

 34     return a.x*b.y-a.y*b.x;

 35 }

 36 bool cmp(point a,point b)

 37 {

 38     return a.y>b.y;

 39 }

 40 

 41 bool intersection1(point p1, point p2, point p3, point p4, point& p)      // 直线相交

 42 {

 43     double a1, b1, c1, a2, b2, c2, d;

 44     a1 = p1.y - p2.y;

 45     b1 = p2.x - p1.x;

 46     c1 = p1.x*p2.y - p2.x*p1.y;

 47     a2 = p3.y - p4.y;

 48     b2 = p4.x - p3.x;

 49     c2 = p3.x*p4.y - p4.x*p3.y;

 50     d = a1*b2 - a2*b1;

 51     if (!dcmp(d))    return false;

 52     p.x = (-c1*b2 + c2*b1) / d;

 53     p.y = (-a1*c2 + a2*c1) / d;

 54     return true;

 55 }

 56 double solve(point p1,point p2,point p3,point p4,point pp,point tp)

 57 {

 58     double ans;

 59     point p11 = point(p1.x,p1.y+1);

 60     if(dcmp(cross(p11-p1,p1-p3))==0)

 61     {

 62         ans = 0;

 63         //cout<<",";

 64     }

 65     else

 66     {

 67         if(dcmp(cross(p11-p1,p1-p3))*dcmp(cross(p1-p2,p3-p4))<0)

 68         {

 69             ans = fabs(cross(p3-pp,tp-pp))/2;

 70             //cout<<",";

 71         }

 72         else ans = 0;

 73     }

 74     return ans;

 75 }

 76 int on_segment( point p1,point p2 ,point p )

 77 {

 78     double max=p1.x > p2.x ? p1.x : p2.x ;

 79     double min =p1.x < p2.x ? p1.x : p2.x ;

 80     double max1=p1.y > p2.y ? p1.y : p2.y ;

 81     double min1=p1.y < p2.y ? p1.y : p2.y ;

 82     if( p.x >=min && p.x <=max &&

 83             p.y >=min1 && p.y <=max1 )

 84         return 1;

 85     else

 86         return 0;

 87 }

 88 int main()

 89 {

 90     int t,i;

 91     cin>>t;

 92     while(t--)

 93     {

 94         for(i = 1; i <= 4 ; i++)

 95             scanf("%lf%lf",&p[i].x,&p[i].y);

 96         sort(p+1,p+3,cmp);

 97         sort(p+3,p+5,cmp);

 98         point pp;

 99         if(intersection1(p[1],p[2],p[3],p[4],pp))

100         {

101             if(!on_segment(p[1],p[2],pp)||!on_segment(p[3],p[4],pp))

102             {

103                 puts("0.00");

104                 continue;

105             }

106         }

107         //cout<<pp.x<<" "<<pp.y<<endl;

108         double ans;

109         point p1 = point(p[3].x-1,p[3].y),p2;

110         point p3 = point(p[1].x-1,p[1].y);

111         if(intersection1(p[1],p[2],p[3],p1,p2)&&on_segment(p[1],p[2],p2))

112         {

113 

114             ans = solve(p[1],p[2],p[3],p[4],pp,p2);

115         }

116         else

117         {

118             intersection1(p[3],p[4],p[1],p3,p2);

119            // cout<<p2.x<<" "<<p2.y<<endl;

120             ans = solve(p[3],p[4],p[1],p[2],pp,p2);

121         }

122         printf("%.2f\n",ans+eps);

123 

124     }

125     return 0;

126 }
View Code

 

你可能感兴趣的:(poj)