poj 3335 Rotating Scoreboard

来源:互联网 发布:mysql官网无法访问 编辑:程序博客网 时间:2024/05/16 18:07
Rotating Scoreboard
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 2719 Accepted: 1020

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

24 0 0 0 1 1 1 1 08 0 0  0 2  1 2  1 1  2 1  2 2  3 2  3 0

Sample Output

YESNO

Source

Tehran 2006 Preliminary

[Submit]   [Go Back]   [Status]   [Discuss]

问题描述:

判断多边形内是否存在一点使得这点都可以观察到边上的任一点(也可以是边上的任何一点都可以观察到这一点,也可以这样认为。实际上题目就是这个意思。。呵呵)

题目分析:

利用半平面交求多边形的内核!

#include <stdio.h>

#include <memory>

#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <map>

#include <cmath>

#include <set>

#include <queue>

#include <time.h>

#include <stdlib.h>

#include <list>

#include <fstream>

using namespace std;

const int N = 105;

struct point

{

    double x, y;

}ps[N], des[N], kernel[N];

int pn;

double MaxDist;   //点和点之间的最大距离,作为延伸线段用


//计算多边形的有向面积,按这种方法,顺时针为负

double getArea(point* ps, int pn)

{

    double ans = 0;

    int i;

    ps[pn] = ps[0];

    for (i = 0; i < pn; i++) ans += (ps[i].x * ps[i + 1].y - ps[i].y * ps[i + 1].x);

    return ans / 2.0;

}


void revPs(point* ps, int pn)         //把ps中的点反序

{

    int l, r;

    l = 0, r = pn - 1;

    point tmp;

    while (l < r)

    {

        tmp = ps[l];

        ps[l] = ps

;

        ps

= tmp;

        l++, r--;

    }

}


inline double dist(point& p1, point& p2)//求的是点p1和点p2的距离

{

    return sqrt(pow(p1.x - p2.x, 2.0) + pow(p1.y - p2.y, 2.0));

}


void extLine(point& st, point& ed, double l)//延伸线段,l为延伸的长度

{


    point tst = st, ted = ed;

    double d = dist(tst, ted);

    double dx, dy;

    dx = (ted.x - tst.x) * l / d;

    dy = (ted.y - tst.y) * l / d;

    ed.x = dx + tst.x;

    ed.y = dy + tst.y;

    dx = -dx;

    dy = -dy;

    st.x = dx + ted.x;

    st.y = dy + ted.y;

}


inline double xmul(point st1, point ed1, point st2, point ed2)//差积定理

{

    return (ed1.x - st1.x) * (ed2.y - st2.y) - (ed1.y - st1.y) * (ed2.x - st2.x);

}


point interPoint(point st1, point ed1, point st2, point ed2)  //得到内核

{

    double eds = fabs(xmul(st1, ed1, st1, ed2));

    double sts = fabs(xmul(st1, ed1, st1, st2));

    point dd;

    dd.x = (eds * st2.x + sts * ed2.x) / (eds + sts);

    dd.y = (eds * st2.y + sts * ed2.y) / (eds + sts);

    return dd;

}


//计算org在由st指向ed的线段的左侧的部分,一般来说st和ed要延伸

void semiPlane(point* org, int on, point* des, int& dn, point st, point ed)

{

    dn = 0;

    extLine(st, ed, MaxDist);

    org[on] = org[0];

    int i, j;

    double ps, pe;

    for (j = 0; j < on; j++)

    {

        ps = xmul(st, ed, st, org[j]);

        pe = xmul(st, ed, st, org[j + 1]);

        if (ps >= 0) des[dn++] = org[j];

        if (ps * pe < 0)

        {

            des[dn++] = interPoint(st, ed, org[j], org[j + 1]);

        }

    }

}

//获得org的内核,放在kernel里

void getKernel(point* org, int on, point* kernel, int& kn)

{

    if (getArea(org, on) < 0)

    {

        revPs(org, on);

    }

    org[on] = org[0];

    int i, dn, j;

    MaxDist = 0;

    for (i = 0; i < on; i++)

    {

        for (j = i + 1; j < on; j++) MaxDist = max(MaxDist, dist(org[i], org[j]));

    }

    for (i = 0; i < on; i++) kernel[i] = org[i];

    kn = on;

    for (i = 0; i < on; i++)

    {

        semiPlane(kernel, kn, des, dn, org[i], org[i + 1]);

        for (j = 0; j < dn; j++) kernel[j] = des[j];

        kn = dn;

    }

}


int main()

{

    int i, t, kn;

    scanf("%d", &t);

    while (t--)

    {

        scanf("%d", &pn);

        for (i = 0; i < pn; i++) scanf("%lf%lf", &ps[i].x, &ps[i].y);

        getKernel(ps, pn, kernel, kn);

        if (!kn) printf("NO\n");

        else printf("YES\n");

    }

    return 0;

}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机忘记id帐号密码怎么办 苹果6手机帐号密码忘记怎么办 狗狗在窝里撒尿怎么办 爸妈和媳妇不好怎么办 如果老婆不用老公的钱怎么办 老公不给老婆钱花怎么办 奶少孩子不愿意吸怎么办 孩子识字少不愿意读书怎么办 夏天孩子不愿意喝水尿量少黄怎么办 孩子不喜欢与别人沟通怎么办 异地恋他爸妈不同意怎么办 刚装修家里很臭怎么办 狗弄得家里很臭怎么办 抑郁症患者不愿意回家见家人怎么办 属猴的人养猫怎么办 对方电话拉黑我怎么办 手机号码换了淘宝账号怎么办 扣扣号有密码无法加好友怎么办 扣扣帐号忘记了怎么办 扣扣帐号被冻结怎么办 xp忘了开机密码怎么办 手机怎样知道好友qq密码怎么办 找回微信密码申诉失败怎么办 若微信号被盗钱怎么办 微信号被倒了怎么办 微信支付密码忘了怎么办 微信钱包密码忘了怎么办 忘记qq锁屏密码怎么办 微信里保密柜密码忘记了怎么办 qq漫游记录密码忘了怎么办 当你很烦的时候怎么办 当你烦的时候怎么办 面对刁蛮不讲理的老婆怎么办 老是想以前的事怎么办 被心机婊陷害了怎么办 分手了还被骚扰怎么办 苹果手机屏幕出现冷暖屏怎么办 我感觉媳妇不漂亮怎么办 90后赚不到钱怎么办 处对象感觉好累怎么办 谈朋友感觉好累怎么办