Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<cmath>
- #include<cstring>
- #include<vector>
- #include<cstdio>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- #define db double
- const db eps=1e-6;
- const int N=1e6+7;
- inline db sqr(db x){
- return x*x;
- }
- inline int dcmp(const db &x){
- if(fabs(x)<eps)return 0;
- return x>0?1:-1;
- }
- struct Point{
- db x,y;
- inline Point(){}
- inline Point(db _x,db _y):x(_x),y(_y){}
- };
- #define Vec Point
- inline Vec operator +(const Vec &a,const Vec &b){
- return Vec(a.x+b.x,a.y+b.y);
- }
- inline Vec operator -(const Vec &a,const Vec &b){
- return Vec(a.x-b.x,a.y-b.y);
- }
- inline void operator +=(Vec &a,const Vec &b){
- a.x+=b.x,a.y+=b.y;
- }
- inline void operator -=(Vec &a,const Vec &b){
- a.x-=b.x,a.y-=b.y;
- }
- inline Vec operator *(const Vec &a,const db &b){
- return Vec(a.x*b,a.y*b);
- }
- inline Vec operator /(const Vec &a,const db &b){
- return Vec(a.x/b,a.y/b);
- }
- inline db Cross(const Vec &a,const Vec &b){
- return a.x*b.y-a.y*b.x;
- }
- inline db Angle(const Vec &a){
- return atan2(a.y,a.x);
- }
- struct Line{
- Point S,T;
- db theta;
- inline Line(){}
- inline Line(const Point &A,const Point &B):S(A),T(B),theta(Angle(B-A)){}
- };
- #define Seg Line
- inline bool operator < (const Line &A,const Line &B){
- double alpha=A.theta-B.theta;
- if(dcmp(alpha))return dcmp(alpha)==-1;
- return dcmp(Cross(A.T-A.S,B.S-A.S))==-1;
- }
- inline bool check(const Line &a,const Line &b){
- return dcmp(Cross(a.T-a.S,b.T-b.S))==0;
- }
- inline Point LineCross(const Line &a,const Line &b){
- Vec u=a.T-a.S;
- Vec v=b.T-b.S;
- Vec w=a.S-b.S;
- db t=Cross(v,w)/Cross(u,v);
- return a.S+u*t;
- }
- //on the right or not
- inline bool Direction(const Line &a,const Point &A){
- return dcmp(Cross(a.T-a.S,A-a.S))==-1;
- }
- Line Q1[N];
- Point Q2[N];
- inline bool Half(Line *A,int n,Point *B,int &m){
- int head=0,tail=0;
- sort(A+1,A+n+1);
- Q1[0]=A[1];
- for(int i=2;i<=n;++i){
- if(!dcmp(A[i].theta-A[i-1].theta))continue;
- while(head<tail&&Direction(A[i],Q2[tail-1]))--tail;
- while(head<tail&&Direction(A[i],Q2[head]))++head;
- Q1[++tail]=A[i];
- Q2[tail-1]=LineCross(A[i],Q1[tail-1]);
- }
- while(head<tail&&Direction(Q1[head],Q2[tail-1]))--tail;
- while(head<tail&&Direction(Q1[tail],Q2[head]))++head;
- Q2[tail]=LineCross(Q1[head],Q1[tail]);
- m=0;
- for(int i=head;i<=tail;++i)B[++m]=Q2[i];
- return 1;
- }
- inline db Area(Point *A,int n){
- db sum=Cross(A[n],A[1]);
- for(int i=1;i<n;++i){
- sum+=Cross(A[i],A[i+1]);
- }
- return sum/2;
- }
- const db Limit=10000;
- Line A[N];
- Point B[N];
- int main(){
- // freopen(".in","r",stdin);
- // freopen(".out","w",stdout);
- int n;scanf("%d",&n);
- for(int i=1;i<=n;++i){
- db a,b,c,d;
- scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
- A[i]=Line(Point(a,b),Point(c,d));
- }
- Point a(0,0);
- Point b(Limit,0);
- Point c(Limit,Limit);
- Point d(0,Limit);
- A[++n]=Line(a,b);
- A[++n]=Line(b,c);
- A[++n]=Line(c,d);
- A[++n]=Line(d,a);
- printf("%.1lf",Half(A,n,B,n)?Area(B,n):0);
- return 0;
- }
- /*
- 3
- 10000 10000 0 5000
- 10000 5000 5000 10000
- 0 5000 5000 0
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement