POJ 3335(半平面交—判断多边形的核是否存在)

来源:互联网 发布:弧形楼梯怎么算法 编辑:程序博客网 时间:2024/05/22 16:41

Rotating Scoreboard
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 7444 Accepted: 2977
Description

This year, ACM/ICPC World finals will be held in a hall in form of a simple polygon. The coaches and spectators are seated along the edges of the polygon. We want to place a rotating scoreboard somewhere in the hall such that a spectator sitting anywhere on the boundary of the hall can view the scoreboard (i.e., his line of sight is not blocked by a wall). Note that if the line of sight of a spectator is tangent to the polygon boundary (either in a vertex or in an edge), he can still view the scoreboard. You may view spectator’s seats as points along the boundary of the simple polygon, and consider the scoreboard as a point as well. Your program is given the corners of the hall (the vertices of the polygon), and must check if there is a location for the scoreboard (a point inside the polygon) such that the scoreboard can be viewed from any point on the edges of the polygon.

Input

The first number in the input line, T is the number of test cases. Each test case is specified on a single line of input in the form n x1 y1 x2 y2 … xn yn where n (3 ≤ n ≤ 100) is the number of vertices in the polygon, and the pair of integers xi yi sequence specify the vertices of the polygon sorted in order.

Output

The output contains T lines, each corresponding to an input test case in that order. The output line contains either YES or NO depending on whether the scoreboard can be placed inside the hall conforming to the problem conditions.

Sample Input

2
4 0 0 0 1 1 1 1 0
8 0 0 0 2 1 2 1 1 2 1 2 2 3 2 3 0
Sample Output

YES
NO
Source

Tehran 2006 Preliminary

开始听到半平面交觉得好复杂啊,这啥东西,核是啥,一直不敢尝试(怠惰),学了之后就觉得,啊这个啊,不是我们高中学的嘛!
半平面交和高中学的线性规划差不多;
什么是半平面交?

·半平面:平面上的直线及其一侧的部分。 ·半平面可由不等式ax+by+c>=0确定。
·在一个有界区域里半平面或半平面的交是一个凸多边形区域。 ·n个半平面的交是一个至多n条边的凸多边形。

再看看什么是多边形的核:

它是平面简单多边形的核是该多边形内部的一个点集,该点集中任意一点与多边形边界上一点的连线都处于这个多边形内部。

如何求解?
这篇博文是带图的,可以很好理解 戳这里
论实现方法有两种,一种是nlogn ,一种是n^2目前只学了后者,前者日后再学
本题就是判断多边形的核是不是存在,判断方法就是求出多边形的核,看它的顶点数目是不是0即可

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <map>#include <stack>#include <vector>#define maxn 110#define maxe 100010typedef long long ll;using namespace std;const double eps=1e-5;const int inf=0x3f3f3f3f3f;typedef double T1;struct Point{    T1 x,y;    Point(){};    Point(T1 a,T1 b)    {        x=a,y=b;    }    void input()    {        scanf("%lf%lf",&x,&y);    }    Point operator +(Point a)    {        Point b(x+a.x,y+a.y);        return b;    }    Point operator -(Point a)    {        Point b(x-a.x,y-a.y);        return b;    }    T1 operator *(Point a)    {        return x*a.x+y*a.y;    }    T1 operator ^(Point a)    {        return x*a.y-y*a.x;    }    bool operator <(Point a)    {        return x<a.x;    }}p[maxn];//求解 由 P1,P2确定的ax+by+c=0的参数void Get_equation(Point p1,Point p2,double &a,double &b,double &c){    a=p1.y-p2.y;    b=p2.x-p1.x;    c=p1.x*p2.y-p1.y*p2.x;}//线段p1,p2和直线ax+by+c的交点Point intersection(Point p1,Point p2,double a,double b,double c){    double u=fabs(a*p1.x+b*p1.y+c);    double v=fabs(a*p2.x+b*p2.y+c);    Point t;    t.x=(p1.x*v+p2.x*u)/(u+v);    t.y=(p1.y*v+p2.y*u)/(u+v);    return t;}Point pap[maxn];Point tmp[maxn];//求解多边形的核void Cut(Point point[],int &cnt,double a,double b,double c){    int t=0;    //看p[i]是不是在所确定直线的顺时针方向,如果是的话就加入答案,不是的话就说明直线一定和以这个点为端点的线段有交点,加入这个交点即可。    for(int i=1;i<=cnt;i++)    {        if(a*point[i].x+b*point[i].y+c<=eps)pap[++t]=point[i];        else        {            if(a*point[i-1].x+b*point[i-1].y+c<eps)pap[++t]=intersection(point[i-1],point[i],a,b,c);            if(a*point[i+1].x+b*point[i+1].y+c<eps)pap[++t]=intersection(point[i+1],point[i],a,b,c);        }    }    for(int i=1;i<=t;i++)    {        point[i]=pap[i];    }    point[0]=pap[t];    point[t+1]=pap[1];    cnt=t;}int main(){    int t;    int n;    //freopen("in.txt","r",stdin);    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            p[i].input();        }        double a,b,c;        p[n+1]=p[1];        p[0]=p[n];        int cnt=n;        int flag=1;        for(int i=0;i<=n+1;i++)        {            tmp[i]=p[i];        }        for(int i=1;i<=n;i++)        {            Get_equation(p[i],p[i+1],a,b,c);            Cut(tmp,cnt,a,b,c);        }        if(cnt)puts("YES");        else puts("NO");    }    return 0;}
阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 公司不运营了怎么办 公司注销了账户怎么办 租户不变更地址怎么办 营业执照忘审了怎么办 工商营业执照年检过期怎么办 个体营业执照没有年报怎么办? 个体工商户一年没有申报怎么办 个体工商户逾期未申报怎么办 个体户没报税过怎么办 农业银行证书过期了怎么办 ca证书丢了怎么办 ca证书被锁怎么办 上个月忘记清卡怎么办 财务人员进入税务黑名单怎么办 社保本丢了怎么办 贷款车辆登记证书怎么办 发票薄丢了怎么办? 汽车发票丢了怎么办 税票弄丢了怎么办 交强险正本丢了怎么办 个体营业执照正本丢失怎么办 简易注销后税务怎么办 拒绝了日历邀请怎么办 老人走丢了怎么办 老人走丢找不到怎么办 没人给介绍对象怎么办 bate365账号被锁怎么办 qq号疑似被盗怎么办 不知道音乐名字怎么办 忘记支付宝登录怎么办 微信被老婆拉黑怎么办 微信群昵称改不了怎么办 微信号设置不了怎么办 修改微信号点不开怎么办 多屏设置失败怎么办 icould密码忘了怎么办 微信号换不了怎么办 微信号改不了怎么办? 无法设置微信号怎么办 公司改名后商标怎么办 公司名称变更后发票怎么办