[poj3130][半平面交]How I Mathematician Wonder What You Are!

传送门
http://poj.org/problem?id=3130

题意:

判断多边形的核是否存在

sol:

半平面交,满足所有半平面的区域显然就是核。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
typedef double s64;
int n,m;
inline int read()
{
    char c;
    int res,flag=0;
    while((c=getchar())>'9'||c<'0') if(c=='-')flag=1;
    res=c-'0';
    while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0';
    return flag?-res:res;
}
const int N=110;
const s64 eps=1e-7;
struct P
{
    s64 x,y;
    friend P operator +(P a,P b) {return (P){a.x+b.x,a.y+b.y};}
    friend P operator -(P a,P b) {return (P){a.x-b.x,a.y-b.y};}
    friend P operator *(P a,s64 b) {return (P){a.x*b,a.y*b};}
    friend s64 operator *(P a,P b) {return a.x*b.y-a.y*b.x;}
    friend s64 operator /(P a,P b) {return a.x*b.x+a.y*b.y;}
}a[N];
struct L
{
    P a,b,v;
    s64 ang;
    friend bool operator <(L a,L b) {return a.ang<b.ang||a.ang==b.ang&&a.v*(b.b-a.a)>0;}
    friend inline P inter(L a,L b)
    {
        P nw=b.a-a.a;
        s64 tt=(nw*a.v)/(a.v*b.v);
        return b.a+b.v*tt;
    }
    friend inline bool jud(P a,L b) {return b.v*(a-b.a)<0;}
}q[N],l[N];
int main()
{
//  freopen("3130.in","r",stdin);
//  freopen(".out","w",stdout);
    while(true)
    {
        n=read();
        if(!n) break;
        int tot=0;
        for(int i=1;i<=n;++i)
        {
            a[i].x=read();
            a[i].y=read();
        }
        a[n+1]=a[1];
        for(int i=1;i<=n;++i)
        {
            l[i].a=a[i];
            l[i].b=a[i+1];
            l[i].v=a[i+1]-a[i];
            l[i].ang=atan2(l[i].v.y,l[i].v.x);
        }
        sort(l+1,l+1+n);
        for(int i=1;i<=n;++i)
        if(l[i].ang!=l[i-1].ang) l[++tot]=l[i];
        n=tot;
        q[1]=l[1];
        q[2]=l[2];
        int R=2;
        int L=1;
        for(int i=3;i<=n;++i)
        {
            while(L<R&&jud(inter(q[R-1],q[R]),l[i])) --R;
            while(L<R&&jud(inter(q[L],q[L+1]),l[i])) ++L;
            q[++R]=l[i];
        }
        while(L<R&&jud(inter(q[R],q[R-1]),q[L])) --R;
        while(L<R&&jud(inter(q[L+1],q[L]),q[R])) ++L;
        if(R-L+1>=3) printf("1\n");
        else printf("0\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值