zoukankan      html  css  js  c++  java
  • csu----J(1812): 三角形和矩形

    多边形交并补模板运用

    J(1812): 三角形和矩形题目

    Submit Page    Summary    Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 7     Solved: 3     SpecialJudge


    Description

    Bobo 有一个三角形和一个矩形,他想求他们交的面积。

    具体地,三角形和矩形由 8 个整数 x1,y1,x2,y2,x3,y3,x4,y4 描述。 表示三角形的顶点坐标是 (x1,y1),(x1,y2),(x2,y1), 矩形的顶点坐标是 (x3,y3),(x3,y4),(x4,y4),(x4,y3).

    Input

    输入包含不超过 30000 组数据。

    每组数据的第一行包含 4 个整数 x1,y1,x2,y2 (x1≠x2,y1≠y2).

    第二行包含 4 个整数 x3,y3,x4,y4 (x3<x4,y3<y4).

    (0≤xi,yi≤104)

    Output

    对于每组数据,输出一个实数表示交的面积。绝对误差或相对误差小于 10-6 即认为正确。

    Sample Input

    1 1 3 3
    0 0 2 2
    0 3 3 1
    0 0 2 2
    4462 1420 2060 2969
    4159 257 8787 2970

    Sample Output

    1.00000000
    0.75000000
    439744.13967527

    Hint

    /*
     * 还要判断是凸包还是凹包,调用相应的函数
     * 面积并,只要和面积减去交即可
     */
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 100005;
    const double eps = 1e-8;
    int dcmp(double x)
    {
        if(x > eps) return 1;
        return x < -eps ? -1 : 0;
    }
    struct Point
    {
        double x, y;
    }z;
    double cross(Point a,Point b,Point c) ///叉积
    {
        return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
    }
    Point intersection(Point a,Point b,Point c,Point d)
    {
        Point p = a;
        double t =((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
        p.x +=(b.x-a.x)*t;
        p.y +=(b.y-a.y)*t;
        return p;
    }
    //计算多边形面积
    double PolygonArea(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)//ConvexPolygonIntersectArea
    {
        Point p[20], tmp[20];
        int tn, sflag, eflag;
        a[na] = a[0], b[nb] = b[0];
        memcpy(p,b,sizeof(Point)*(nb + 1));
        for(int i = 0; i < na && nb > 2; i++)
        {
            sflag = dcmp(cross(a[i + 1], p[0],a[i]));
            for(int j = tn = 0; j < nb; j++, sflag = eflag)
            {
                if(sflag>=0) tmp[tn++] = p[j];
                eflag = dcmp(cross(a[i + 1], p[j + 1],a[i]));
                if((sflag ^ eflag) == -2)
                    tmp[tn++] = intersection(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 PolygonArea(p, nb);
    }
    double SPIA(Point a[], Point b[], int na, int nb)///SimplePolygonIntersectArea 调用此函数
    {
        int i, j;
        Point t1[4], t2[4];
        double res = 0, num1, num2;
        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];
            num1 = dcmp(cross(t1[1], t1[2],t1[0]));
            if(num1 < 0) swap(t1[1], t1[2]);
            for(j = 2; j < nb; j++)
            {
                t2[1] = b[j - 1], t2[2] = b[j];
                num2 = dcmp(cross(t2[1], t2[2],t2[0]));
                if(num2 < 0) swap(t2[1], t2[2]);
                res += CPIA(t1, t2, 3, 3) * num1 * num2;
            }
        }
        return res;
    }
    bool cmp_node(Point a,Point b)
    {
        double ans=(b.x-z.x)*(a.y-z.y)-(b.y-z.y)*(a.x-z.x);
        if(fabs(ans)<eps)
            return sqrt(pow(a.x-z.x,2)+pow(a.y-z.y,2))<sqrt(pow(b.x-z.x,2)+pow(b.y-z.y,2));
        return ans>0;
    }
    void sort_j(Point p[],int n)
    {
        int pos=0;
        for(int i=0;i<n;i++)
        {
            if(p[pos].y>p[i].y)
                pos=i;
            if(p[pos].y==p[pos].y&&p[pos].x>p[i].x)
                pos=i;
        }
        swap(p[pos],p[0]);
        z=p[0];
        sort(p+1,p+n,cmp_node);
    }
    Point p1[maxn], p2[maxn];
    int n1, n2;
    int main()
    {
        double x1,x2,x3,x4,y1,y2,y3,y4;
        while(~scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4))
        {
            p1[0].x=x2;p1[0].y=y1;
            p1[1].x=x1;p1[1].y=y1;
            p1[2].x=x1;p1[2].y=y2;
            p2[0].x=x4;p2[0].y=y3;
            p2[1].x=x3;p2[1].y=y3;
            p2[2].x=x4;p2[2].y=y4;
            p2[3].x=x3;p2[3].y=y4;
            sort_j(p1,3);
            sort_j(p2,4);
            double Area = SPIA(p1, p2,3,4);
            printf("%.8f
    ",Area);
        }
        return 0;
    }
    
  • 相关阅读:
    JZOI 4020 Revolution
    JZOJ 4018 Magic
    JZOJ 4017 逃跑
    JZOJ 4016 圈地为王
    JZOJ 4015 数列
    JZOJ 3960 鸡腿の出行
    BZOJ 5005 & JZOI 3959 鸡腿の乒乓
    GCJ2009B&JZOJ 4033 Min Perimeter
    jzoj 3948 Hanoi 塔
    [纯符][纯粹的无聊] 神奇的递推式
  • 原文地址:https://www.cnblogs.com/ke-yi-/p/10175815.html
Copyright © 2011-2022 走看看