• HihoCoder


    题意:给定X轴上的一些三角形,求面积并。 每个三角形的给出形式是Li,Ri,Xi,Yi,表示三个顶点分别是(Li,0);(Ri,0);(Xi,Yi),且满足Li<=Xi<=Ri;

    思路:我们把这些三角形全部涂黑,就会发现只需要找到这些关键的“拐点”即可,最后求出每两个拐点之间形成的梯形的面积即可。 那么为了找拐点,我们需要把所有的X求出来,然后用这些X和线段树求交点,每个X保留一个最高的Y,这个就是拐点了。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    typedef long long ll;
    const double eps=1e-3;
    const double pi=acos(-1.0);
    struct point{
        double x,y;
        point(double a=0,double b=0):x(a),y(b){}
    };
    int dcmp(double x){ return fabs(x)<eps?0:(x<0?-1:1);}
    point operator +(point A,point B) { return point(A.x+B.x,A.y+B.y);}
    point operator -(point A,point B) { return point(A.x-B.x,A.y-B.y);}
    point operator *(point A,double p){ return point(A.x*p,A.y*p);}
    point operator /(point A,double p){ return point(A.x/p,A.y/p);}
    point rotate(point A,double rad){ //向量的旋转
        return point(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
    }
    bool operator ==(const point& a,const point& b) {
         return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
    }
    double dot(point A,point B){ return A.x*B.x+A.y*B.y;}
    double det(point A,point B){ return A.x*B.y-A.y*B.x;}
    double dot(point O,point A,point B){ return dot(A-O,B-O);}
    double det(point O,point A,point B){ return det(A-O,B-O);}
    double length(point A){ return sqrt(dot(A,A));}
    double angle(point A,point B){ return acos(dot(A,B)/length(A)/length(B));} //夹角
    point jiaopoint(point p,point v,point q,point w) //如果平行,除0会有问题
    {   //p+tv q+tw,点加向量表示直线,求直线交点
        //如果是线段,还应该实现判定是否相离或者平行
        point u=p-q;
        double t=det(w,u)/det(v,w);
        return p+v*t;
    }
    point GetCirPoint(point a,point b,point c)
    {
        point p=(a+b)/2;    //ab中点
        point q=(a+c)/2;    //ac中点
        point v=rotate(b-a,pi/2.0),w=rotate(c-a,pi/2.0);   //中垂线的方向向量
        if (dcmp(length(det(v,w)))==0)    //平行
        {
            if(dcmp(length(a-b)+length(b-c)-length(a-c))==0) return (a+c)/2;
            if(dcmp(length(b-a)+length(a-c)-length(b-c))==0) return (b+c)/2;
            if(dcmp(length(a-c)+length(c-b)-length(a-b))==0) return (a+b)/2;
        }
        return jiaopoint(p,v,q,w);
    }
    int main()
    {
    
    }

    当然也可以直接套多边形面积并的板子:

    #include<bits/stdc++.h>
    using namespace std;
    #define mp make_pair
    typedef long long ll;
    const double inf=1e200;
    const double eps=1e-12;
    const double pi=4*atan(1.0);
    int dcmp(double x){ return fabs(x)<eps?0:(x<0?-1:1);}
    struct point{
        double x,y;
        point(double a=0,double b=0):x(a),y(b){}
    };
    point operator +(point A,point B) { return point(A.x+B.x,A.y+B.y);}
    point operator -(point A,point B) { return point(A.x-B.x,A.y-B.y);}
    point operator *(point A,double p){ return point(A.x*p,A.y*p);}
    point operator /(point A,double p){ return point(A.x/p,A.y/p);}
    bool operator ==(const point& a,const point& b){
        return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;
    }
    double dot(point A,point B){ return A.x*B.x+A.y*B.y;}
    double det(point A,point B){ return A.x*B.y-A.y*B.x;}
    double det(point O,point A,point B){ return det(A-O,B-O);}
    double length(point A){ return sqrt(dot(A,A));}
    double area(vector<point>p){
        double ans=0; int sz=p.size();
        for(int i=1;i<sz-1;i++) ans+=det(p[i]-p[0],p[i+1]-p[0]);
        return ans/2.0;
    }
    double seg(point O,point A,point B){
        if(dcmp(B.x-A.x)==0) return (O.y-A.y)/(B.y-A.y);
        return (O.x-A.x)/(B.x-A.x);
    }
    vector<point>pp[110];
    pair<double,int>s[110*60];
    double polyunion(vector<point>*p,int N){ //需要这些点是顺时针
        double res=0;
        for(int i=0;i<N;i++){
            int sz=p[i].size();
            for(int j=0;j<sz;j++){
                int m=0;
                s[m++]=mp(0,0);
                s[m++]=mp(1,0);
                point a=p[i][j],b=p[i][(j+1)%sz];
                for(int k=0;k<N;k++){
                    if(i!=k){
                        int sz2=p[k].size();
                        for(int ii=0;ii<sz2;ii++){
                            point c=p[k][ii],d=p[k][(ii+1)%sz2];
                            int c1=dcmp(det(b-a,c-a));
                            int c2=dcmp(det(b-a,d-a));
                            if(c1==0&&c2==0){
                                if(dcmp(dot(b-a,d-c))){
                                    s[m++]=mp(seg(c,a,b),1);
                                    s[m++]=mp(seg(c,a,b),-1);
                                }
                            }
                            else{
                                double s1=det(d-c,a-c);
                                double s2=det(d-c,b-c);
                                if(c1>=0&&c2<0) s[m++]=mp(s1/(s1-s2),1);
                                else if(c1<0&&c2>=0) s[m++]=mp(s1/(s1-s2),-1);
                            }
                        }
                    }
                }
                sort(s,s+m);
                double pre=min(max(s[0].first,0.0),1.0),now,sum=0;
                int cov=s[0].second;
                for(int j=1;j<m;j++){
                    now=min(max(s[j].first,0.0),1.0);
                    if(!cov) sum+=now-pre;
                    cov+=s[j].second;
                    pre=now;
                }
                res+=det(a,b)*sum;
            }
        }
        return res/2;
    }
    int main()
    {
        int N,M,i,j; point tp,ta,tb; ta.y=tb.y=0.0;
        scanf("%d",&N);
        for(i=0;i<N;i++){
            scanf("%lf%lf%lf%lf",&ta.x,&tb.x,&tp.x,&tp.y);
            pp[i].push_back(tb);
            pp[i].push_back(ta);
            pp[i].push_back(tp);
        }
        double t1=0,t2=polyunion(pp,N);
        for(i=0;i<N;i++) t1+=area(pp[i]);
        printf("%.2lf
    ",-t2);
        return 0;
    }
  • 相关阅读:
    爬虫-基于scrapy-redis两种形式的分布式爬虫
    爬虫-Scrapy框架(CrawlSpider)
    爬虫-User-Agent和代理池
    爬虫-scrapy框架之递归解析和post请求
    爬虫-scrapy数据的持久化存储
    爬虫-scrapy框架简介和基础应用
    爬虫-移动端数据爬取
    爬虫-图片懒加载技术、selenium和PhantomJS
    爬虫-验证码处理
    爬虫-requests模块
  • 原文地址:https://www.cnblogs.com/hua-dong/p/11494021.html
Copyright © 2020-2023  润新知