POJ 2451 求半面交

简介:

题意:求半面想交后的面积,题目数据较大,使用o(n*logn)算法。

这题WA两次忘了m<3的情况,不应该啊= = 。

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int mm=20005;
typedef double DIY;
struct point
{
    DIY x,y;
    point() {}
    point(DIY _x,DIY _y):x(_x),y(_y) {}
} g[mm];
double Direction(point pi,point pj,point pk) //判断向量PiPj在向量PiPk的顺逆时针方向 +顺-逆0共线
{
    return (pj.x-pi.x)*(pk.y-pi.y)-(pk.x-pi.x)*(pj.y-pi.y);
}
point MakeVector(point &P,point &Q)
{
    return point(Q.x-P.x,Q.y-P.y);
}
DIY CrossProduct(point P,point Q)
{
    return P.x*Q.y-P.y*Q.x;
}
DIY MultiCross(point P,point Q,point R)
{
    return CrossProduct(MakeVector(Q,P),MakeVector(Q,R));
}
struct halfPlane
{
    point s,t;
    double angle;
    halfPlane() {}
    halfPlane(point _s,point _t):s(_s),t(_t) {}
    halfPlane(DIY sx,DIY sy,DIY tx,DIY ty):s(sx,sy),t(tx,ty) {}
    void GetAngle()
    {
        angle=atan2(t.y-s.y,t.x-s.x);
    }
} hp[mm],q[mm];
point IntersectPoint(halfPlane P,halfPlane Q)
{
    DIY a1=CrossProduct(MakeVector(P.s,Q.t),MakeVector(P.s,Q.s));
    DIY a2=CrossProduct(MakeVector(P.t,Q.s),MakeVector(P.t,Q.t));
    return point((P.s.x*a2+P.t.x*a1)/(a2+a1),(P.s.y*a2+P.t.y*a1)/(a2+a1));
}
bool cmp(halfPlane P,halfPlane Q)
{
    if(fabs(P.angle-Q.angle)<1e-8)
        return MultiCross(P.s,P.t,Q.s)>0;
    return P.angle<Q.angle;
}
bool IsParallel(halfPlane P,halfPlane Q)
{
    return fabs(CrossProduct(MakeVector(P.s,P.t),MakeVector(Q.s,Q.t)))<1e-8;
}
void HalfPlaneIntersect(int n,int &m)
{
    sort(hp,hp+n,cmp);
    int i,l=0,r=1;
    for(m=i=1; i<n; ++i)
        if(hp[i].angle-hp[i-1].angle>1e-8)hp[m++]=hp[i];
    n=m;
    m=0;
    q[0]=hp[0],q[1]=hp[1];
    for(i=2; i<n; ++i)
    {
        if(IsParallel(q[r],q[r-1])||IsParallel(q[l],q[l+1]))return;
        while(l<r&&MultiCross(hp[i].s,hp[i].t,IntersectPoint(q[r],q[r-1]))>0)--r;
        while(l<r&&MultiCross(hp[i].s,hp[i].t,IntersectPoint(q[l],q[l+1]))>0)++l;
        q[++r]=hp[i];
    }
    while(l<r&&MultiCross(q[l].s,q[l].t,IntersectPoint(q[r],q[r-1]))>0)--r;
    while(l<r&&MultiCross(q[r].s,q[r].t,IntersectPoint(q[l],q[l+1]))>0)++l;
    q[++r]=q[l];
    for(i=l; i<r; ++i)
        g[m++]=IntersectPoint(q[i],q[i+1]);
}
int main()
{
    int n,m;
    point a,b;
    point p[5];
    p[0].x=0,p[0].y=0;
    p[1].x=10000,p[1].y=0;
    p[2].x=10000,p[2].y=10000;
    p[3].x=0,p[3].y=10000;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
            hp[i]=halfPlane(a,b);
            hp[i].GetAngle();
        }
        for(int i=0; i<4; i++)
        {
            hp[n+i]=halfPlane(p[i],p[(i+1)%4]);
            hp[i+n].GetAngle();
        }
        HalfPlaneIntersect(n+4,m);
        if(m<3)
        {
            puts("0.0");
            continue;
        }
        double ans=0;
        for(int i=0; i<m; i++)
            ans+=Direction(g[i],g[(i+1)%m],p[0]);
        ans=ans<0?-ans/2:ans/2;
        printf("%.1f\n",ans);
    }
    return 0;
}


目录
相关文章
|
SQL 前端开发 关系型数据库
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
246 0
全表数据核对 ,行数据核对,列数据核对,Mysql 8.0 实例(sample database classicmodels _No.3 )
|
Java 数据库连接 mybatis
项目移植到原先mybasis项目里出现BindingException: Invalid bound statement (not found): **selectPage
项目移植到原先mybasis项目里出现BindingException: Invalid bound statement (not found): **selectPage
202 1
|
12月前
|
存储 安全 Java
从入门到精通:Java Map全攻略,一篇文章就够了!
【10月更文挑战第19天】本文介绍了Java编程中重要的数据结构——Map,通过问答形式讲解了Map的基本概念、创建、访问与修改、遍历方法、常用实现类(如HashMap、TreeMap、LinkedHashMap)及其特点,以及Map在多线程环境下的使用和性能优化技巧,适合初学者和进阶者学习。
434 4
|
Python
如何在 Python 中导入模块
【8月更文挑战第29天】
199 5
|
人工智能 边缘计算 搜索推荐
未来移动应用与系统的发展趋势与挑战
随着移动技术的迅速发展,移动应用与系统正经历着前所未有的变革与创新。本文探讨了移动应用开发的最新趋势,移动操作系统的演进,以及未来面临的挑战与解决方案。
|
Java API PHP
使用oss服务上传/下载对象
使用oss服务上传/下载对象
1034 2
|
Ubuntu Linux 数据安全/隐私保护
WSL安装QQ
WSL安装QQ
398 1
Ant Design pro删除模块笔记(二)
Ant Design pro删除模块笔记(二)
184 0
HMI-58-【多媒体】重构底部菜单
今天的这个没有新的内容,就是计划重新构建下底部菜单,开始是在每个界面里面都做了底部菜单,开始我以为每个界面都不一样,和面我研究了一下发现,每个界面的底部菜单都是一样的呀,那我们就好所了,开始重构。把底部菜单移到他的父页面中。
|
XML 前端开发 数据库
Layui之动态树(树形菜单)详解2
Layui之动态树(树形菜单)详解2
121 0