BZOJ1845 [Cqoi2005] 三角形面积并

题意

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser   autoint Logout 捐赠本站
Problem 1845. -- [Cqoi2005] 三角形面积并

1845: [Cqoi2005] 三角形面积并

Time Limit: 3 Sec   Memory Limit: 64 MB
Submit: 1664   Solved: 443
[ Submit][ Status][ Discuss]

Description

给出n个三角形,求它们并的面积。

Input

第一行为n(N < = 100), 即三角形的个数 以下n行,每行6个整数x1, y1, x2, y2, x3, y3,代表三角形的顶点坐标。坐标均为不超过10 ^ 6的实数,输入数据保留1位小数

Output

输出并的面积u, 保留两位小数

Sample Input

2
0.0 0.0 2.0 0.0 1.0 1.0
1.0 0.0 3.0 0.0 2.0 1.0

Sample Output

1.75

HINT

Source

[ Submit][ Status][ Discuss]

HOME Back

分析

参照Claris的题解。

求出所有交点后从左往右扫描线,用每段的中位线去截所有三角形,算出长度并后乘以该段长度即可,时间复杂度\(O(n^3\log n)\)

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
    while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co double eps=1e-9,INF=1e6;
il int sig(double x) {return abs(x)<eps?0:(x>0?1:-1);}
struct P{double x,y;};
il bool cmp(co P&u,co P&v) {return u.x<v.x;}
il P operator+(co P&u,co P&v) {return (P){u.x+v.x,u.y+v.y};}
il P operator-(co P&u,co P&v) {return (P){u.x-v.x,u.y-v.y};}
il P operator*(co P&u,double k) {return (P){u.x*k,u.y*k};}
il double cross(co P&u,co P&v) {return u.x*v.y-u.y*v.x;}
il bool has_intersection(co P&a,co P&b,co P&p,co P&q){
    return sig(cross(b-a,p-a))*sig(cross(b-a,q-a))<0&&
           sig(cross(q-p,a-p))*sig(cross(q-p,b-p))<0;
}
il P line_intersection(co P&a,co P&b,co P&p,co P&q){
    return a+(b-a)*(cross(p-a,q-p)/cross(b-a,q-p));
}

co int N=300;
int n,m;
P tri[N][4],seg[N];
double px[N*N],ans;
double cal(double x){
    P D=(P){x,-INF},U=(P){x,INF};
    int m=0;
    for(int i=0,k=0;i<n;++i,k=0){
        double y[2];
        for(int j=0;j<3;++j)if(has_intersection(tri[i][j],tri[i][j+1],D,U))
            y[k++]=line_intersection(tri[i][j],tri[i][j+1],D,U).y;
        if(k) seg[m++]=(P){min(y[0],y[1]),max(y[0],y[1])};
    }
    if(m>1) sort(seg,seg+m,cmp);
    double l=-INF,r=-INF,t=0;
    for(int i=0;i<m;++i){
        if(sig(seg[i].x-r)>0) t+=r-l,l=seg[i].x;
        r=max(r,seg[i].y);
    }
    return t+r-l;
}
int main(){
//  freopen(".in","r",stdin),freopen(".out","w",stdout);
    read(n);
    for(int i=0;i<n;++i){
        for(int j=0;j<3;++j)
            scanf("%lf%lf",&tri[i][j].x,&tri[i][j].y),px[m++]=tri[i][j].x;
        tri[i][3]=tri[i][0];
    }
    for(int i=0;i<n;++i)for(int j=0;j<i;++j)
        for(int k=0;k<3;++k)for(int l=0;l<3;++l)
            if(has_intersection(tri[i][k],tri[i][k+1],tri[j][l],tri[j][l+1]))
                px[m++]=line_intersection(tri[i][k],tri[i][k+1],tri[j][l],tri[j][l+1]).x;
    sort(px,px+m);
    for(int i=1;i<m;++i)if(sig(px[i]-px[i-1]))
        ans+=(px[i]-px[i-1])*cal((px[i]+px[i-1])/2);
    return printf("%.2lf\n",ans-eps),0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/10662993.html