判断多边形的核是否存在 poj3130&&poj3335

poj3130点击打开链接

poj3335点击打开链接

拿的别人的模板

poj3335

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 0x7fffffff
#define exp 1e-10
#define PI 3.141592654
using namespace std;
const int maxn=111;
struct Point
{
    double x,y;
    Point (double x=0,double y=0):x(x),y(y){}
}an[maxn];
typedef Point Vector;
struct Line
{
    Point p;
    Vector v;
    double ang;
    Line (){}
    Line (Point p,Vector v):p(p),v(v){ang=atan2(v.y,v.x); }
    friend bool operator < (Line a,Line b)
    {
        return a.ang<b.ang;
    }
}bn[maxn];
Vector operator + (Vector A,Vector B) {return Vector(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); }
Vector operator / (Vector A,double p) {return Vector(A.x/p , A.y/p); }
int dcmp(double x) {if (fabs(x)<exp) return 0;return x>0 ? 1 : -1; }
double cross(Vector A,Vector B)
{
    return A.x*B.y-B.x*A.y;
}
bool OnLeft(Line L,Point p)
{
    return cross(L.v,p-L.p)>=0;///点P在有向直线L的左边(>=0说明在线上也算)
}
Point GetIntersection(Line a,Line b)
{
    Vector u=a.p-b.p;
    double t=cross(b.v,u)/cross(a.v,b.v);
    return a.p+a.v*t;
}
    
int HalfplaneIntersection(Line *L,int n,Point *poly)
{
    sort(L,L+n);

    int first,last;
    Point *p=new Point[n];
    Line *q=new Line[n];
    q[first=last=0]=L[0];
    for (int i=1 ;i<n ;i++)
    {
        while (first<last && !OnLeft(L[i],p[last-1])) last--;
        while (first<last && !OnLeft(L[i],p[first])) first++;
        q[++last]=L[i];
        if (fabs(cross(q[last].v , q[last-1].v))<exp)
        {
            last--;
            if (OnLeft(q[last] , L[i].p)) q[last]=L[i];
        }
        if (first<last) p[last-1]=GetIntersection(q[last-1],q[last]);
    }
    while (first<last && !OnLeft(q[first],p[last-1])) last--;
    if (last-first<=1) return 0;
    p[last]=GetIntersection(q[last],q[first]);
    int m=0;
    for (int i=first ;i<=last ;i++) poly[m++]=p[i];
    return m;
}
void calPolygon(Point *p, int n, double &area, bool &shun)
{
    p[n] = p[0];
    area = 0;
    double tmp;
    for (int i = 0; i < n; i++)
        area += p[i].x * p[i + 1].y - p[i].y * p[i + 1].x;
    area /= 2.0;
    if (shun = area < 0)
        area = -area;
}
bool calCore(Point *ps, int n)
{
    Line l[maxn];
    ps[n] = ps[0];
    bool shun;
    double area;
    calPolygon(ps, n, area, shun);
    if (shun)
        for (int i = 0; i < n; i++)
            bn[i] = Line(ps[i], ps[i] - ps[i + 1]);
    else
        for (int i = 0; i < n; i++)
            bn[i] = Line(ps[i], ps[i + 1] - ps[i]);
    Point pp[maxn];
    return HalfplaneIntersection(bn, n, pp);
}
int main()
{
    int t;
    int n;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);
        Point cn[maxn];
        for (int i=0 ;i<n ;i++)
        {
            scanf("%lf%lf",&cn[i].x,&cn[i].y);
        }
        if (!calCore(cn,n)) puts("NO");
        else puts("YES");
    }
    return 0;
}

poj3130

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 0x7fffffff
#define exp 1e-10
#define PI 3.141592654
using namespace std;
const int maxn=111;
struct Point
{
    double x,y;
    Point (double x=0,double y=0):x(x),y(y){}
}an[maxn];
typedef Point Vector;
struct Line
{
    Point p;
    Vector v;
    double ang;
    Line (){}
    Line (Point p,Vector v):p(p),v(v){ang=atan2(v.y,v.x); }
    friend bool operator < (Line a,Line b)
    {
        return a.ang<b.ang;
    }
}bn[maxn];
Vector operator + (Vector A,Vector B) {return Vector(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); }
Vector operator / (Vector A,double p) {return Vector(A.x/p , A.y/p); }
int dcmp(double x) {if (fabs(x)<exp) return 0;return x>0 ? 1 : -1; }
double cross(Vector A,Vector B)
{
    return A.x*B.y-B.x*A.y;
}
bool OnLeft(Line L,Point p)
{
    return cross(L.v,p-L.p)>=0;///点P在有向直线L的左边(>=0说明在线上也算)
}
Point GetIntersection(Line a,Line b)
{
    Vector u=a.p-b.p;
    double t=cross(b.v,u)/cross(a.v,b.v);
    return a.p+a.v*t;
}

int HalfplaneIntersection(Line *L,int n,Point *poly)
{
    sort(L,L+n);

    int first,last;
    Point *p=new Point[n];
    Line *q=new Line[n];
    q[first=last=0]=L[0];
    for (int i=1 ;i<n ;i++)
    {
        while (first<last && !OnLeft(L[i],p[last-1])) last--;
        while (first<last && !OnLeft(L[i],p[first])) first++;
        q[++last]=L[i];
        if (fabs(cross(q[last].v , q[last-1].v))<exp)
        {
            last--;
            if (OnLeft(q[last] , L[i].p)) q[last]=L[i];
        }
        if (first<last) p[last-1]=GetIntersection(q[last-1],q[last]);
    }
    while (first<last && !OnLeft(q[first],p[last-1])) last--;
    if (last-first<=1) return 0;
    p[last]=GetIntersection(q[last],q[first]);
    int m=0;
    for (int i=first ;i<=last ;i++) poly[m++]=p[i];
    return m;
}
void calPolygon(Point *p, int n, double &area, bool &shun)
{
    p[n] = p[0];
    area = 0;
    double tmp;
    for (int i = 0; i < n; i++)
        area += p[i].x * p[i + 1].y - p[i].y * p[i + 1].x;
    area /= 2.0;
    if (shun = area < 0)
        area = -area;
}
bool calCore(Point *ps, int n)
{
    Line l[maxn];
    ps[n] = ps[0];
    bool shun;
    double area;
    calPolygon(ps, n, area, shun);
    if (shun)
        for (int i = 0; i < n; i++)
            bn[i] = Line(ps[i], ps[i] - ps[i + 1]);
    else
        for (int i = 0; i < n; i++)
            bn[i] = Line(ps[i], ps[i + 1] - ps[i]);
    Point pp[maxn];
    return HalfplaneIntersection(bn, n, pp);
}
int main()
{
    int t;
    int n;

    while (~scanf("%d",&n)&&n)
    {
        Point cn[maxn];
        for (int i=0 ;i<n ;i++)
        {
            scanf("%lf%lf",&cn[i].x,&cn[i].y);
        }
        if (!calCore(cn,n)) puts("0");
        else puts("1");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值