您的位置:首页 > 其它

POJ 1584 A Round Peg in a Ground Hole(是否凸包 && 圆是否在凸包内)

2015-08-22 16:28 477 查看
A Round Peg in a Ground Hole

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 5676Accepted: 1821
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
按逆时针或顺时针给出n个点和一个圆的圆心和半径 ,问这n个点是否能组成凸包,能的话,圆是否在凸包内(相切也算)
判定凸包时要注意允许相邻边共线
判定圆是否在凸包内时,我一开始是判断圆心(x,y)是否在凸包内,然后判断圆心的上下左右四个点是否在凸包内,结果WA了。
后来发现了组数据才发现这四个点并不是极限,只适用于边平行于x,y轴的凸包
正解是判断圆心到每一条边的距离 于 半径的大小,大于半径的则说明圆不在凸包内
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <algorithm>
#include <queue>
#include <map>
#include <cmath>
#define N 151
#define eps 1e-6
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define _sign(x) ((x > eps)? 1:((x) < -eps? 2:0))
using namespace std;
struct Point
{
    double x, y;
}p
,R;
struct Line
{
    double a,b,c;
};
int n;
double xmult(struct Point pb, struct Point p1, struct Point p2)   //叉积
{
    return  (p1.x - pb.x) * (p2.y - pb.y) - (p2.x - pb.x) * (p1.y - pb.y);
}
int is_convex()                           //是否凸包
{
    int s[3] = {1, 1, 1};
    for(int i = 0; i < n && s[1] | s[2]; i++)
         s[_sign( xmult( p[(i+1)%n], p[(i+2)%n], p[i])) ] = 0;
    return s[1] | s[2];
}
int inside_convex(Point q)         //是否凸包内的点
{
    int s[3] = {1, 1, 1};
    for(int i = 0; i < n && s[1] | s[2]; i++)
        s[_sign( xmult( p[(i+1)%n], q, p[i])) ] = 0;
    return s[1] | s[2];
}
Line twoPoLine(Point p1,Point p2)        //两点的直线方程
{
	Line L;
	L.a = p1.y - p2.y;
	L.b = p2.x - p1.x;
	L.c = p1.x*p2.y - p2.x*p1.y;
	return L;
}
double poToLine(Point p,Line L)           //点到直线的距离
{
	return fabs(L.a*p.x + L.b*p.y + L.c)/sqrt(L.a*L.a + L.b*L.b);
}
int main()
{
    double r;
    while(scanf("%d",&n) && n >= 3)
    {
        scanf("%lf%lf%lf", &r, &R.x, &R.y);
        for(int i = 0; i < n; i++)
        {
            scanf("%lf%lf", &p[i].x, &p[i].y);
        }
        if(is_convex())                //判断给的所有点是否为凸包
        {
             if(inside_convex(R))      //圆心是否在凸包内
             {
                 p
.x = p[0].x;      
                 p
.y = p[0].y;
                 bool flag = true;
                 for(int i = 0; i < n;i++)  
                 {
                     Line L  = twoPoLine(p[i], p[i+1]); //相邻两点的直线方程
                     double dis = poToLine(R, L);   //圆心到任意一边的距离
                     if(dis < r)                  //判断圆心到任意一边的距离 与 半径的大下
                     {
                         flag = false;
                         break;
                     }
                 }
                 if(flag)
                 printf("PEG WILL FIT\n");
                    else printf("PEG WILL NOT FIT\n");

             }
             else printf("PEG WILL NOT FIT\n");
        }
        else
            printf("HOLE IS ILL-FORMED\n");
    }
    return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: