题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1812

解法:套凸多边交模板。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 555;
const int maxsin = 10;
const double eps = 1e-8;
const double PI = acos(-1.0);
int dcmp(double x){
    if(x>eps) return 1;
    return x<-eps?-1:0;
}

struct Point{
    double x,y;
    Point(){x=y=0;}
    Point(double a,double b){x=a,y=b;}
    Point operator -(const Point &b)const{
        return Point(x-b.x,y-b.y);
    }
    Point operator +(const Point &b) const{
        return Point(x+b.x,y+b.y);
    }
    double dot(const Point &b)const{
        return x*b.x+y*b.y;
    }
    double cross(const Point &b, const Point &c)const {
        return (b.x-x)*(c.y-y)-(c.x-x)*(b.y-y);
    }
};
Point LineCross(const Point &a, const Point &b, const Point &c, const Point &d){
    double u=a.cross(b,c), v=b.cross(a,d);
    return Point((c.x*v+d.x*u)/(u+v), (c.y*v+d.y*u)/(u+v));
}
double Area(Point p[], int n){
    if(n<3) return 0.0;
    double s = p[0].y*(p[n-1].x-p[1].x);
    p[n]=p[0];
    for(int i=1; i<n; i++){
        s+=p[i].y*(p[i-1].x-p[i+1].x);
    }
    return fabs(s*0.5);
}
double CPIA(Point a[], Point b[], int na, int nb){
    Point p[maxsin], tmp[maxsin];
    int i,j,tn,sflag,eflag;
    a[na]=a[0],b[nb]=b[0];
    memcpy(p,b,sizeof(Point)*(nb+1));
    for(i=0; i<na&&nb>2; i++){
        sflag=dcmp(a[i].cross(a[i+1],p[0]));
        for(j=tn=0; j<nb; ++j,sflag=eflag){
            if(sflag>=0) tmp[tn++]=p[j];
            eflag=dcmp(a[i].cross(a[i+1],p[j+1]));
            if((sflag^eflag)==-2)
                tmp[tn++]=LineCross(a[i],a[i+1],p[j],p[j+1]);
        }
        memcpy(p,tmp,sizeof(Point)*tn);
        nb=tn,p[nb]=p[0];
    }
    if(nb<3) return 0.0;
    return Area(p,nb);
}
double solve(Point a[], Point b[], int na, int nb){
    int i,j;
    Point t1[4],t2[4];
    double res=0,if_clk_t1,if_clk_t2;
    a[na]=t1[0]=a[0], b[nb]=t2[0]=b[0];
    for(i=2; i<na; i++){
        t1[1]=a[i-1],t1[2]=a[i];
        if_clk_t1=dcmp(t1[0].cross(t1[1],t1[2]));
        if(if_clk_t1<0) swap(t1[1],t1[2]);
        for(j=2; j<nb; j++){
            t2[1]=b[j-1],t2[2]=b[j];
            if_clk_t2=dcmp(t2[0].cross(t2[1],t2[2]));
            if(if_clk_t2<0) swap(t2[1],t2[2]);
            res+=CPIA(t1,t2,3,3)*if_clk_t1*if_clk_t2;
        }
    }
    return Area(a,na)+Area(b,nb)-res;
}
Point p1[maxn],p2[maxn];
int n1,n2;
int main()
{
    double x1,y1,x2,y2,x3,y3,x4,y4;
    while(scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2)!=EOF)
    {
        scanf("%lf%lf%lf%lf", &x3,&y3,&x4,&y4);
        n1 = 3;
        n2 = 4;
        p1[0].x=x1,p1[0].y=y1;
        p1[1].x=x1,p1[1].y=y2;
        p1[2].x=x2,p1[2].y=y1;

        p2[0].x=x3,p2[0].y=y3;
        p2[1].x=x3,p2[1].y=y4;
        p2[2].x=x4,p2[2].y=y4;
        p2[3].x=x4,p2[3].y=y3;


        double ans = abs(Area(p1, n1) + Area(p2, n2) - solve(p1,p2,n1,n2));
        printf("%.8f\n", ans);
    }
    return 0;
}