ACM博客_kuangbin

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

A Round Peg in a Ground Hole

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4438   Accepted: 1362

Description

The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to one another using a wooden peg that fits into pre-cut holes in each piece to be attached. The pegs have a circular cross-section and so are intended to fit inside a round hole. 
A recent factory run of computer desks were flawed when an automatic grinding machine was mis-programmed. The result is an irregularly shaped hole in one piece that, instead of the expected circular shape, is actually an irregular polygon. You need to figure out whether the desks need to be scrapped or if they can be salvaged by filling a part of the hole with a mixture of wood shavings and glue. 
There are two concerns. First, if the hole contains any protrusions (i.e., if there exist any two interior points in the hole that, if connected by a line segment, that segment would cross one or more edges of the hole), then the filled-in-hole would not be structurally sound enough to support the peg under normal stress as the furniture is used. Second, assuming the hole is appropriately shaped, it must be big enough to allow insertion of the peg. Since the hole in this piece of wood must match up with a corresponding hole in other pieces, the precise location where the peg must fit is known. 
Write a program to accept descriptions of pegs and polygonal holes and determine if the hole is ill-formed and, if not, whether the peg will fit at the desired location. Each hole is described as a polygon with vertices (x1, y1), (x2, y2), . . . , (xn, yn). The edges of the polygon are (xi, yi) to (xi+1, yi+1) for i = 1 . . . n − 1 and (xn, yn) to (x1, y1).

Input

Input consists of a series of piece descriptions. Each piece description consists of the following data: 
Line 1 < nVertices > < pegRadius > < pegX > < pegY > 
number of vertices in polygon, n (integer) 
radius of peg (real) 
X and Y position of peg (real) 
n Lines < vertexX > < vertexY > 
On a line for each vertex, listed in order, the X and Y position of vertex The end of input is indicated by a number of polygon vertices less than 3.

Output

For each piece description, print a single line containing the string: 
HOLE IS ILL-FORMED if the hole contains protrusions 
PEG WILL FIT if the hole contains no protrusions and the peg fits in the hole at the indicated position 
PEG WILL NOT FIT if the hole contains no protrusions but the peg will not fit in the hole at the indicated position

Sample Input

5 1.5 1.5 2.0
1.0 1.0
2.0 2.0
1.75 2.0
1.0 3.0
0.0 2.0
5 1.5 1.5 2.0
1.0 1.0
2.0 2.0
1.75 2.5
1.0 3.0
0.0 2.0
1

Sample Output

HOLE IS ILL-FORMED
PEG WILL NOT FIT

Source

Mid-Atlantic 2003

题意:

给出N个点,一个圆的半径和圆心坐标:

  1. 如果N个点构成的多边形不是凸多边形,输出:HOLE IS ILL-FORMED
  2. 如果N个点构成凸多边形,圆在凸多边形内,输出:PEG WILL FIT
  3. 如果N个点构成凸多边形,圆不在凸多边内,输出:PEG WILL NOT FIT

分析:

首先是判断给出了多边形是不是凸多边形。然后判断圆包含在凸多边形中。

一定要保证圆心在凸多边形里面,然后判断圆心到每条线段的距离要大于等于半径。

#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;const double eps = 1e-8;
int sgn(double x)
{if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}
struct Point
{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}Point operator -(const Point &b)const{return Point(x - b.x,y - b.y);}//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x;}//点积double operator *(const Point &b)const{return x*b.x + y*b.y;}void input(){scanf("%lf%lf",&x,&y);}
};
struct Line
{Point s,e;Line(){}Line(Point _s,Point _e){s = _s;e = _e;}//两直线相交求交点//第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交//只有第一个值为2时,交点才有意义pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);}
};//*判断线段相交
bool inter(Line l1,Line l2)
{returnmax(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}//两点距离
double dist(Point a,Point b)
{return sqrt((a-b)*(a-b));
}//判断凸多边形,允许共线边
//点的编号0~n-1,可以是顺时针和逆时针
bool isConvex(Point poly[],int n){bool s[3];memset(s,false,sizeof s);for(int i=0;i<n;i++){s[sgn( (poly[(i+1)%n]-poly[i])^(poly[(i+2)%n]-poly[i]) )+1]=true;if(s[0]&&s[2])  return false;}return true;
}//点到线段的距离,返回点到线段最近的点
Point NearestPointToLineSeg(Point p,Line L)
{Point result;double t=((p-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));if(t>=0&&t<=1){result.x=L.s.x+(L.e.x-L.s.x)*t;result.y=L.s.y+(L.e.y-L.s.y)*t;}else{if(dist(p,L.s)<dist(p,L.e))result=L.s;elseresult=L.e;}return result;
}//判断点在线段上
bool OnSeg(Point P,Line L)
{returnsgn((L.s-P)^(L.e-P)) == 0 &&sgn((P.x - L.s.x) * (P.x - L.e.x)) <= 0 &&sgn((P.y - L.s.y) * (P.y - L.e.y)) <= 0;
}//*判断点在凸多边形内
//点形成一个凸包,而且按逆时针排序(如果是顺时针把里面的<0改为>0)
//点的编号:0~n-1
//返回值:
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inConvexPoly(Point a,Point p[],int n)
{for(int i = 0;i < n;i++){if(sgn((p[i]-a)^(p[(i+1)%n]-a)) < 0)return -1;else if(OnSeg(a,Line(p[i],p[(i+1)%n])))return 0;}return 1;
}//*判断点在任意多边形内
//射线法,poly[]的顶点数要大于等于3,点的编号0~n-1
//返回值
//-1:点在凸多边形外
//0:点在凸多边形边界上
//1:点在凸多边形内
int inPoly(Point p,Point poly[],int n)
{int cnt;Line ray,side;cnt = 0;ray.s = p;ray.e.y = p.y;ray.e.x = -100000000000.0;//-INF,注意取值防止越界for(int i = 0;i < n;i++){side.s = poly[i];side.e = poly[(i+1)%n];if(OnSeg(p,side))return 0;//如果平行轴则不考虑if(sgn(side.s.y - side.e.y) == 0)continue;if(OnSeg(side.s,ray)){if(sgn(side.s.y - side.e.y) > 0)cnt++;}else if(OnSeg(side.e,ray)){if(sgn(side.e.y - side.s.y) > 0)cnt++;}else if(inter(ray,side))cnt++;}if(cnt % 2 == 1)return 1;else return -1;
}int n;
Point o;//圆心
double R;//半径
Point p[110];
int main()
{while(scanf("%d",&n)!=EOF){if(n<3) break;scanf("%lf%lf%lf",&R,&o.x,&o.y);for(int i=0;i<n;i++)p[i].input();if(!isConvex(p,n)){//不是凸多边形printf("HOLE IS ILL-FORMED\n");continue;}//圆心不在凸多边形内if(inPoly(o,p,n)<0){printf("PEG WILL NOT FIT\n");continue;}bool flag=false;for(int i=0;i<n;i++){if(sgn(dist(o,NearestPointToLineSeg(o,Line(p[i],p[(i+1)%n]))) -R ) <0 ){flag=true;break;}}if(flag)    printf("PEG WILL NOT FIT\n");else        printf("PEG WILL FIT\n");}return 0;
}

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

  1. POJ - 1584 A Round Peg in a Ground Hole(综合几何)

    题目链接:点击查看 题目大意:给出n个点,以及一个圆心和半径,首先判断这n个点能否构成凸包,若能,继续判断圆是否在凸包内 题目分析:这个题目确实非常综合,考察了判断凸包问题,判断圆是否在凸包内,只要保 ...

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

    题意:给出一个多边形和一个圆,问是否是凸多边形,若是则再问圆是否在凸多边形内部. 分3步: 1.判断是否是凸多边形 2.判断点是否在多边形内部 3.判断点到各边的距离是否大于等于半径 上代码: #in ...

  3. 【POJ1584】A Round Peg in a Ground Hole,第一次的计算几何

    Time:2016.07.15 Author:xiaoyimi 转载注明出处谢谢 思路: 算是计算几何的第一个题吧 判断是否为凸多边形用相邻边(向量)的叉积判断 (要求叉积的符号相同) 向量a,b,若 ...

  4. 判断直线与线段 是否相交 + 加入误差 故需要判断重点 poj 3304 Segments

    题目来源:http://poj.org/problem?id=3304 分析: 题目大意:给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出 ...

  5. POJ 1584 计算几何 凸包

    链接: http://poj.org/problem?id=1584 题意: 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个 ...

  6. poj 1584(凸包+点在凸多边形内+圆在凸多边形内)

    题意: 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全在n边形内部. 解题思路: 1.判断该多边形是否是凸包,由于 ...

  7. poj 1039 Pipe (判断 直线和 线段 是否相交 并 求交点)

    http://poj.org/problem?id=1039 题意:已知电缆是由一段段直的管道连接而成的,并知道这些管道的位置,问一束光从最左边射进来,你可以调节光入射的位置和角度,问最远能射到多远. ...

  8. Codeforces Round #376 (Div. 2) D. 80-th Level Archeology —— 差分法 + 线段扫描法

    题目链接:http://codeforces.com/contest/731/problem/D D. 80-th Level Archeology time limit per test 2 sec ...

  9. Codeforces Round #686 (Div. 3) F. Array Partition(二分+线段树)

    题意:一段区间,让你分割成三段,第一段取max,第二段取min,第三段取max.问你怎么分割这个区间. 题解: 三个区间我们可以用两个点将一段区间分成三段区间. 二分:我们首先找这个题有关的单调性,我 ...

最新文章

  1. mysql学习之旅-数据库自动备份-测试环境搭建
  2. Leetcode 210. 课程表 II 解题思路及C++实现
  3. 常见的原生javascript DOM操作
  4. Spring Cloud【Finchley】-15 查看Zuul的路由端点和过滤器
  5. 在 Kubernetes 上弹性深度学习训练利器 -- Elastic Training Operator
  6. leetcode(1)485——最大连续 1 的个数(C++)
  7. 把设备分享给每个Docker Container
  8. 个性化推荐认知之----数字化转型浪潮下,产品经理应如何重新认知个性化推荐?...
  9. butterfly配置 hexo_Hexo博客之butterfly主题优雅魔改系列(持续更新)
  10. python hdf5 —— h5py
  11. 【Python3之模块及包的导入】
  12. 分布式本质论:高吞吐、高可用、可扩展 (1)
  13. 第二篇:基于小米手机的,第三方recovery教学
  14. 电子签的背后江湖:腾讯、蚂蚁、字节跳动的较量
  15. 06 第五章 一阶逻辑等值演算与推理
  16. CSS指北——浮动(Floating)规则详解
  17. CAD矩形阵列应用与实战技巧
  18. 计算机图文混合排版教学设计,Word图文混排教学设计
  19. Mac Google浏览器出现:您目前无法访问 XX.XX.XX.XX,因为此网站发送了 Google Chrome 无法处理的杂乱凭据
  20. House of sprit一谈

热门文章

  1. 事务日志已满,原因为“ACTIVE_TRANSACTION”
  2. TCP/IP详解学习笔记-基本概念
  3. 面向对象三大特性 -- 继承,封装,多态
  4. LightOJ 1093 - Ghajini 线段树
  5. 在MAC系统的eclipse里打开android sdk manager
  6. delphi DLL动态链接库
  7. Linux下运行纯dos软件,在linux下运行dos软件(转)
  8. springboot actuator_Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行情况监控...
  9. 异步和同步区别是什么_一次相亲经历,我彻底搞懂了什么叫阻塞非阻塞,同步异步...
  10. java路线_2021年Java学习路线图—精心整理