【POJ 1584】 A Round Peg in a Ground Hole (判凸包+判圆在凸包内)

【POJ 1584】 A Round Peg in a Ground Hole (判凸包+判圆在凸包内)

这题题面是一大坑。。长长的 明显是给我这种英语渣准备的。。。

大体意思是给出一个多边形的点 按顺时针或逆时针给出 判断是否为凸包 同时给出一个圆(圆心坐标+半径) 问这个圆在不在多边形内

首先顺逆时针不确定 我的做法是输入时先判断顺时针还是逆时针输入 然后统统变成逆时针来走 就是根据两种情况传入不同的枚举起点 终点 和加减(具体见代码

判凸包用建凸包的叉成法即可 既然逆时针走 那么如果是凸包 向量一定是逆时针转动 同时还可以判断圆心是不是在凸包内 看当前起点与圆心的向量叉成当前边 为负(顺时针) 说明圆心在多边形内(边上也算 因为圆半径有0的情况

如果不为凸包 直接输出 HOLE IS ILL-FORMED

如果圆心不在凸包内 输出PEG WILL NOT FIT

否则再判断圆是否完全被凸包包裹 枚举凸包每个边即可 如果出现某条边与圆心距离小于圆的半径 说明圆不再凸包内 如果能遍历完所有边 则在凸包内

求点到线段的距离用线段两段点与改点构成的向量进行叉乘 由于构成三角形 并且点到线段距离是三角形高 所以可以得出 (h*w)/2 = l1xl2/2 w为线段长度 x为叉乘 叉乘得到的是平行四边形面积 所以需要除2 化简可得 h = (l1xl2)/w 这就是点到线段的距离公式

至此 程序完成

PS:发现个好东西 大家WA不要不要了的可以去测测

http://midatl.fireduck.com/archive/2003/problems/MidAtlantic-2003/problem-D/

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
#define esp 1e-5

using namespace std;

typedef struct Point Point;
typedef struct Line Line;

struct Line
{
    double x,y;

    bool operator > (const Line a)const//顺时针
    {
        return x*a.y-y*a.x > esp;
    }

    bool operator < (const Line a)const//逆时针
    {
        return x*a.y-y*a.x < -esp;
    }

    bool operator == (const Line a)const//共线
    {
        return x*a.y-y*a.x < esp && x*a.y-y*a.x > -esp;
    }

    double operator * (const Line a)const//叉乘
    {
        return fabs(x*a.y-y*a.x);
    }

};

struct Point
{
    double x,y;

    Line operator - (const Point a)const//得到两点向量
    {
        Line l;
        l.x = x-a.x;
        l.y = y-a.y;
        return l;
    }

    double operator + (const Point a)const//两点间距离
    {
        return (x-a.x)*(x-a.x)+(y-a.y)*(y-a.y);
    }

};

Point yx;
double r;
vector <Point> vc;
int n;

int cal(int low,int high,int stp)//判断是否为凸多边形 同时判断圆心是否在内部
{
    Line l1,l2;
    Point p1,p2,p3;
    int i;
    int f = 1;

    p1 = vc[low];
    p2 = vc[low+stp];
    l1 = p2-p1;
    l2 = yx-p1;
    if(l2 > l1) f = 0;

    for(i = low+stp*2; i != high+stp; i += stp)
    {
        p3 = vc[i];

        l1 = p2-p1;
        l2 = p3-p1;

        if(l2 > l1) return 0;
        l1 = p3-p2;
        l2 = yx-p2;
        if(f && l2 > l1) f = 0;

        p1 = p2;
        p2 = p3;
    }
    return f+1;
}

bool Challenge()//判断圆是否在多边形内
{
    int i;
    Point p;
    Line l1,l2;
    p = vc[0];
    for(i = 1; i < vc.size(); ++i)
    {
        l1 = p-yx;
        l2 = vc[i]-yx;
        if((l1*l2)/sqrt(vc[i]+p) - r < -esp) return 0;
        p = vc[i];
    }
    return 1;
}

int main()
{
    freopen("in.in","r",stdin);
    Point tmp,pt,p1,p2;
    Line l1,l2;
    int f;
    while(~scanf("%d",&n) && n >= 3)
    {
        f = 0;
        vc.clear();
        scanf("%lf %lf %lf",&r,&yx.x,&yx.y);
        scanf("%lf %lf",&tmp.x,&tmp.y);
        vc.push_back(tmp);
        p1 = tmp;

        scanf("%lf %lf",&p2.x,&p2.y);
        vc.push_back(p2);

        n -= 2;
        while(n--)
        {
            scanf("%lf %lf",&pt.x,&pt.y);
            vc.push_back(pt);
            if(!f)
            {
                l1 = p2 - p1;
                l2 = pt - p1;
                if(l1 > l2) f = 1;
                else if(l1 < l2) f = -1;
            }
            p1 = p2;
            p2 = pt;
        }
        vc.push_back(tmp);

        if(f == 1) f = cal(0,vc.size()-1,1);//顺时针输入
        else if(f == -1) f = cal(vc.size()-1,0,-1);//逆时针输入
        else f = 0;//未构成凸多边形

        if(f == 2)
        {
            if(Challenge()) puts("PEG WILL FIT");
            else puts("PEG WILL NOT FIT");
        }
        else if(f == 1) puts("PEG WILL NOT FIT");
        else puts("HOLE IS ILL-FORMED");
    }
    return 0;
}

小记:

这么晚写这个题解 觉得自己也蛮拼的 明天上午结训会 还要上去讲话(不是你们想的呢样。。我是棵青葱。。。锻炼锻炼吧也算

至此 训练计划POJ部分初级结束 在这深夜 时间好快 从去年暑假 到现在 一年时光 我也为自己的进步惊讶 但确实不够 只能说稍微比一般人快一点 跟那些大牛学校比 。。。。只能呵呵然后被虐……多校就能看得出 还有前一次跟山科一同做了份网赛(组队 确实比人家弱很多 跟他们14级的比也是 差太多了 也算常态吧 往往什么事都是这样 越努力 云雾越会消散 然而渐渐的你却发现 面前是堵高墙 想要继续 就要不断爬 可翻过高墙 你又发现后面有条河 有过河又看到座高山。。。
就是这样 这个金字塔没有顶层 只有不断地筑高 没有人知道会爬多高 也没有尽头 然而弱还在塔底呢。。。

在这小小感慨一下。应该都看不到吧。。。看不到我看不到我看不到我……既然选择了这条路 爬着跪着算什么 至少还在前行 就是好的!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-03 21:17:21

【POJ 1584】 A Round Peg in a Ground Hole (判凸包+判圆在凸包内)的相关文章

POJ 1584 A Round Peg in a Ground Hole 判断凸多边形 点到线段距离 点在多边形内

首先判断是不是凸多边形 然后判断圆是否在凸多边形内 kuangbin的板子,但是有些地方不明白. 判断多边形不是凸多边形后,为什么用判断点是否在凸多边形内的模板交WA了,而用判断点是否在任意多边形内的模板A了 而且判断点是否在任意多边形的注释,返回值为什么又说是凸多边形~~~ POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内) #include <iostream> #include <cstdio> #inclu

poj 1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形 + 圆心是否在凸多边形内 + 圆是否在凸多边形内部

题目来源: http://poj.org/problem?id=1584 题意: 给一个多边形, 一个圆心以及半径. 首先判断是否为凸多边形. 如果是凸多边形, 再判断,圆是否在凸多边形内部. 分析: 1) 先判断是否为凸多边形 ,题目给出的顶点是有序的, 即顺时针或是 逆时针.用叉积方向判断. 2) 判断圆在多边形内, 首先判断 圆心是否在多边形内部, 是的话,然后再 判断 圆心到多边形 所有边的 距离d >= r , 即可. 代码如下: const int Max_N = 1005; con

poj 1584 A Round Peg in a Ground Hole(计算几何)

A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5603   Accepted: 1788 Description The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to on

POJ 1584 A Round Peg in a Ground Hole(凸包判定&amp;&amp;圆在凸包内判定)

博客原文地址:http://blog.csdn.net/xuechelingxiao/article/details/39178777 A Round Peg in a Ground Hole 题目大意:按顺时针或逆时针给出多边形的顶点坐标.圆的半径及圆心坐标. 1.求多边形是否是个凸包,若不是输出"HOLE IS ILL-FORMED". 2.如果多边形为凸包,判定圆是否在凸包内,若凸包在园内,输出"PEG WILL FIT",若不在,输出"PEG WI

POJ 1584 A Round Peg in a Ground Hole --判定点在形内形外形上

题意: 给一个圆和一个多边形,多边形点可能按顺时针给出,也可能按逆时针给出,先判断多边形是否为凸包,再判断圆是否在凸包内. 解法: 先判是否为凸包,沿着i=0~n,先得出初始方向dir,dir=1为逆时针,dir=-1为顺时针,然后如果后面有两个相邻的边叉积后得出旋转方向为nowdir,如果dir*nowdir < 0,说明方向逆转了,即出现了凹点,说明不是凸多边形. 然后判圆是否在多边形内: 先判圆心是否在多边形内,用环顾法,然后如果在之内,则依次判断圆心与每条凸包边的距离与半径的距离,如果所

POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)

http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全在n边形内部. 分析 1.判断给出了多边形是不是凸多边形. 2.判断圆包含在凸多边形中:一定要保证圆心在凸多边形里面.然后判断圆心到每条线段的距离要大于等于半径.. #include <iostream> #include <stdio.h> #include <string.h

POJ 1584 A Round Peg in a Ground Hole

先判断是不是N多边形,求一下凸包,如果所有点都用上了,那么就是凸多边形 判断圆是否在多边形内, 先排除圆心在多边形外的情况 剩下的情况可以利用圆心到每条边的最短距离与半径的大小来判断 #include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<list> #include<algorithm> us

POJ 1584 A Round Peg in a Ground Hole(点到直线距离,圆与多边形相交,多边形是否为凸)

题意:给出一个多边形和一个圆,问是否是凸多边形,若是则再问圆是否在凸多边形内部. 分3步: 1.判断是否是凸多边形 2.判断点是否在多边形内部 3.判断点到各边的距离是否大于等于半径 上代码: #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using na

POJ 1584 A Round Peg in a Ground Hole(凸多边形判断 + 点是否在多边形内 + 点到线段的最短距离)

题目:传送门 题意:给你一个圆和一个多边形, 判断多边形是不是凸多边形,如果是,接着判断圆是否在凸多边形内部. #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #include <map> #include <vector> #include <set> #inclu