Advertisement
yicongli

POJ2451

Mar 1st, 2019
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.01 KB | None | 0 0
  1. #include<cmath>
  2. #include<cstring>
  3. #include<vector>
  4. #include<cstdio>
  5. #include<iostream>
  6. #include<algorithm>
  7.  
  8. using namespace std;
  9.  
  10. #define db double
  11.  
  12. const db eps=1e-6;
  13. const int N=1e6+7;
  14.  
  15. inline db sqr(db x){
  16.     return x*x;
  17. }
  18.  
  19. inline int dcmp(const db &x){
  20.     if(fabs(x)<eps)return 0;
  21.     return x>0?1:-1;
  22. }
  23.  
  24. struct Point{
  25.     db x,y;
  26.    
  27.     inline Point(){}
  28.     inline Point(db _x,db _y):x(_x),y(_y){}
  29.    
  30. };
  31.  
  32. #define Vec Point
  33.  
  34. inline Vec operator +(const Vec &a,const Vec &b){
  35.     return Vec(a.x+b.x,a.y+b.y);
  36. }
  37.  
  38. inline Vec operator -(const Vec &a,const Vec &b){
  39.     return Vec(a.x-b.x,a.y-b.y);
  40. }
  41.  
  42. inline void operator +=(Vec &a,const Vec &b){
  43.     a.x+=b.x,a.y+=b.y;
  44. }
  45.  
  46. inline void operator -=(Vec &a,const Vec &b){
  47.     a.x-=b.x,a.y-=b.y;
  48. }
  49.  
  50. inline Vec operator *(const Vec &a,const db &b){
  51.     return Vec(a.x*b,a.y*b);
  52. }
  53.  
  54. inline Vec operator /(const Vec &a,const db &b){
  55.     return Vec(a.x/b,a.y/b);
  56. }
  57.  
  58. inline db Cross(const Vec &a,const Vec &b){
  59.     return a.x*b.y-a.y*b.x;
  60. }
  61.  
  62. inline db Angle(const Vec &a){
  63.     return atan2(a.y,a.x);
  64. }
  65.  
  66. struct Line{
  67.     Point S,T;
  68.     db theta;
  69.    
  70.     inline Line(){}
  71.     inline Line(const Point &A,const Point &B):S(A),T(B),theta(Angle(B-A)){}
  72.    
  73. };
  74.  
  75. #define Seg Line
  76.  
  77. inline bool operator < (const Line &A,const Line &B){
  78.     double alpha=A.theta-B.theta;
  79.     if(dcmp(alpha))return dcmp(alpha)==-1;
  80.     return dcmp(Cross(A.T-A.S,B.S-A.S))==-1;
  81. }
  82.  
  83. inline bool check(const Line &a,const Line &b){
  84.     return dcmp(Cross(a.T-a.S,b.T-b.S))==0;
  85. }
  86.  
  87. inline Point LineCross(const Line &a,const Line &b){
  88.     Vec u=a.T-a.S;
  89.     Vec v=b.T-b.S;
  90.     Vec w=a.S-b.S;
  91.     db t=Cross(v,w)/Cross(u,v);
  92.     return a.S+u*t;
  93. }
  94. //on the right or not
  95. inline bool Direction(const Line &a,const Point &A){
  96.     return dcmp(Cross(a.T-a.S,A-a.S))==-1;
  97. }
  98.  
  99. Line Q1[N];
  100. Point Q2[N];
  101.  
  102. inline bool Half(Line *A,int n,Point *B,int &m){
  103.     int head=0,tail=0;
  104.     sort(A+1,A+n+1);
  105.     Q1[0]=A[1];
  106.     for(int i=2;i<=n;++i){
  107.         if(!dcmp(A[i].theta-A[i-1].theta))continue;
  108.         while(head<tail&&Direction(A[i],Q2[tail-1]))--tail;
  109.         while(head<tail&&Direction(A[i],Q2[head]))++head;
  110.         Q1[++tail]=A[i];
  111.         Q2[tail-1]=LineCross(A[i],Q1[tail-1]);
  112.     }
  113.     while(head<tail&&Direction(Q1[head],Q2[tail-1]))--tail;
  114.     while(head<tail&&Direction(Q1[tail],Q2[head]))++head;
  115.     Q2[tail]=LineCross(Q1[head],Q1[tail]);
  116.     m=0;
  117.     for(int i=head;i<=tail;++i)B[++m]=Q2[i];
  118.     return 1;
  119. }
  120.  
  121. inline db Area(Point *A,int n){
  122.     db sum=Cross(A[n],A[1]);
  123.     for(int i=1;i<n;++i){
  124.         sum+=Cross(A[i],A[i+1]);
  125.     }
  126.     return sum/2;
  127. }
  128.  
  129. const db Limit=10000;
  130.  
  131. Line A[N];
  132. Point B[N];
  133.  
  134. int main(){
  135. //  freopen(".in","r",stdin);
  136. //  freopen(".out","w",stdout);
  137.     int n;scanf("%d",&n);
  138.     for(int i=1;i<=n;++i){
  139.         db a,b,c,d;
  140.         scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
  141.         A[i]=Line(Point(a,b),Point(c,d));
  142.     }
  143.     Point a(0,0);
  144.     Point b(Limit,0);
  145.     Point c(Limit,Limit);
  146.     Point d(0,Limit);
  147.     A[++n]=Line(a,b);
  148.     A[++n]=Line(b,c);
  149.     A[++n]=Line(c,d);
  150.     A[++n]=Line(d,a);
  151.     printf("%.1lf",Half(A,n,B,n)?Area(B,n):0);
  152.     return 0;
  153. }
  154. /*
  155. 3
  156. 10000 10000 0 5000
  157. 10000 5000 5000 10000
  158. 0 5000 5000 0
  159.  
  160. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement