hdu 4629 Burning

acm.hdu.edu.cn/showproblem.php?pid=4629

题意:

给出n个三角形,分别求出他们相交i次的面积,i∈[1,n]

在求面积并的基础上修改

求面积并:https://www.cnblogs.com/TheRoadToTheGold/p/12221288.html

当计算中位线的长度时,把端点离散化,利用前缀和差分计算覆盖次数

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const double eps=1e-10;
const int inf=101;

int n;
struct Point
{
    double x,y;
    
    Point(double x_=0,double y_=0) : x(x_),y(y_) {}    

}tri[51][4],seg[51];

typedef Point Vector;

double px[25001],ans[51];
double has[25001];
int cnt[101];

Point operator - (Point A,Point B) { return Point(A.x-B.x,A.y-B.y); }
Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); }
Vector operator * (Vector A,double p) { return Vector(A.x*p,A.y*p); }

int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0 ? -1 : 1;
}

double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}

bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2)
{
    double c1=Cross(a2-a1,b1-a1),c2=Cross(a2-a1,b2-a1),c3=Cross(b2-b1,a1-b1),c4=Cross(b2-b1,a2-b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}

Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{
    Vector u=P-Q;
    double t=Cross(w,u)/Cross(v,w);
    return P+v*t;
}    

void cal(double line,double h)
{
    Point up(line,inf),down(line,-inf);
    int m=0,k,tot=0;
    double py[3];
    for(int i=1;i<=n;++i)
    {
        k=0;
        for(int j=0;j<3;++j)
            if(SegmentProperIntersection(tri[i][j],tri[i][j+1],up,down))
                py[++k]=GetLineIntersection(tri[i][j],tri[i][j+1]-tri[i][j],up,up-down).y;
        if(k) 
        {
            seg[++m]=Point(min(py[1],py[2]),max(py[1],py[2]));
            has[++tot]=py[1];
            has[++tot]=py[2];
        }
    }
    sort(has+1,has+tot+1);
    int opl,opr;
    memset(cnt,0,sizeof(cnt));
    for(int i=1;i<=m;++i)
    {
        opl=lower_bound(has+1,has+tot+1,seg[i].x)-has;
        opr=lower_bound(has+1,has+tot+1,seg[i].y)-has;
        cnt[opl]++;
        cnt[opr]--;
    }
    for(int i=1;i<=tot;++i) cnt[i]+=cnt[i-1];
    for(int i=1;i<tot;++i) ans[cnt[i]]+=(has[i+1]-has[i])*h;
}

int main()
{
    int T,m;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        m=0;
        for(int i=1;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=1;i<n;++i)
            for(int j=i+1;j<=n;++j)
                for(int k=0;k<3;++k)
                    for(int l=0;l<3;++l)
                        if(SegmentProperIntersection(tri[i][k],tri[i][k+1],tri[j][l],tri[j][l+1]))
                            px[++m]=GetLineIntersection(tri[i][k],tri[i][k+1]-tri[i][k],tri[j][l],tri[j][l+1]-tri[j][l]).x;
        sort(px+1,px+m+1);
        memset(ans,0,sizeof(ans));
        for(int i=2;i<=m;++i)
            if(dcmp(px[i]-px[i-1]))
                cal((px[i]+px[i-1])/2,px[i]-px[i-1]);
        for(int i=1;i<=n;++i) printf("%.10lf
",ans[i]);
    }
    return 0;
}

Burning

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 705    Accepted Submission(s): 283
Special Judge


Problem Description
The sky is BURNING,and you find there are n triangles on a plane.
For every point p,if there's exactly k triangles contains it,then define it's thickness as k.
For every i from 1 to n,calculate the area of all points whose thickness is i.
 
Input
The first line contains integer T(T <= 5),denote the number of the test cases.
For each test cases,the first line contains integer n(1 <= n <= 50),denote the number of the triangles.
Then n lines follows,each line contains six integers x1, y1, x2, y2, x3, y3, denote there's a triangle with vertices (x1, y1), (x2, y2), (x3, y3).
0 <= xi, yi <= 100 for every i.
 
Output
For each test cases,print n lines,the i-th is the total area for thickness i.
The answer will be considered correct if its absolute error doesn't exceed 10-4.
 
Sample Input
1 5 29 84 74 64 53 66 41 49 60 2 23 38 47 21 3 58 89 29 70 81 7 16 59 14 64 62 63 2 30 67
 
Sample Output
1348.5621251916 706.2758371223 540.0414504206 9.9404623255 0.0000000000
Hint
Triangle can be degenerated(3 points on a line,even 3 points are the same).
 
Author
WJMZBMR
 
Source
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12222507.html