poj1279 Art Gallery

题目描述:

vjudge

POJ

题解:

半平面交求核的面积。

板子?

代码:

#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1550;
const double eps = 1e-8;
int dcmp(double x)
{
    if(fabs(x)<=eps)return 0;
    return x>0?1:-1;
}
struct Point
{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
    Point operator + (const Point&a)const{return Point(x+a.x,y+a.y);}
    Point operator - (const Point&a)const{return Point(x-a.x,y-a.y);}
    Point operator * (const double&a)const{return Point(x*a,y*a);}
    double operator ^ (const Point&a)const{return x*a.y-y*a.x;}
};
typedef Point Vector;
typedef vector<Point> Pol;
double ang(const Vector&a){return atan2(a.x,a.y);}
struct Line
{
    Point p;
    Vector v;
    Line(){}
    Line(Point p,Vector v):p(p),v(v){}
    bool operator < (const Line&a)const{return ang(v)<ang(a.v);}
};
int T,n;
Point p[N],tp[N];
Line s[N],ts[N];
bool Onleft(Line l,Point p){return dcmp(l.v^(p-l.p))>0;}
Point L_L(Line a,Line b)
{
    double t = ((b.p-a.p)^b.v)/(a.v^b.v);
    return a.p+a.v*t;
}
int bpmj(Pol&P)
{
    sort(s+1,s+1+n);
    int hd,tl;
    ts[hd=tl=1]=s[1];
    for(int i=2;i<=n;i++)
    {
        while(hd<tl&&!Onleft(s[i],tp[tl-1]))tl--;
        while(hd<tl&&!Onleft(s[i],tp[hd]))hd++;
        ts[++tl] = s[i];
        if(!dcmp(ts[tl].v^ts[tl-1].v))
        {
            tl--;
            if(Onleft(ts[tl],s[i].p))ts[tl]=s[i];
        }
        if(hd<tl)tp[tl-1]=L_L(ts[tl-1],ts[tl]);
    }
    while(hd<tl&&!Onleft(ts[hd],tp[tl-1]))tl--;
    if(tl-hd<=1)return 0;
    tp[tl] = L_L(ts[hd],ts[tl]);
    for(int i=hd;i<=tl;i++)P.push_back(tp[i]);
    return 1;
}
bool check()
{
    double ans = 0;
    for(int i=2;i<=n;i++)
        ans+=((p[i-1]-p[1])^(p[i]-p[1]));
    return dcmp(ans)>=0;
}
double S_(Pol&P)
{
    double ans = 0.0;
    for(int i=2,lim=(int)P.size();i<lim;i++)
        ans+=((P[i]-P[0])^(P[i-1]-P[0]));
    return fabs(ans)/2;
}
void work()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    if(!check())
        for(int i=2,j=n;i<j;i++,j--)swap(p[i],p[j]);
    for(int i=1;i<n;i++)s[i] = Line(p[i],p[i+1]-p[i]);
    s[n] = Line(p[n],p[1]-p[n]);
    Pol P;
    int now = bpmj(P);
    if(!now)
    {
        puts("0.00");
    }else
    {
        printf("%.2lf
",S_(P));
    }
}
int main()
{
//    freopen("tt.in","r",stdin);
    scanf("%d",&T);
    while(T--)work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10984958.html