您的位置:首页 > 其它

poj_1584 A Round Peg in a Ground Hole(凸包判断凸多边形+判断点在多边形内)

2016-11-23 16:48 381 查看
A Round Peg in a Ground Hole
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 6641 Accepted: 2124
DescriptionThe 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 havea 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 figureout 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 bestructurally 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 correspondinghole 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).InputInput 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.OutputFor each piece description, print a single line containing the string:HOLE IS ILL-FORMED if the hole contains protrusionsPEG WILL FIT if the hole contains no protrusions and the peg fits in the hole at the indicated positionPEG WILL NOT FIT if the hole contains no protrusions but the peg will not fit in the hole at the indicated positionSample 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
题意比较难看懂,主要是被protrusions这个词的意思迷惑了,在这道题中 the holes contains protrusions 应该是非凸多边形的洞的意思。
通过多边形的凸包的顶点数是否等于原多边形的顶点数去判断。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 1010#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;struct Point{double x, y;Point(double x = 0, double y = 0) : x(x), y(y) { }};typedef Point Vector;Vector operator + (Vector A, Vector B){return Vector(A.x + B.x, A.y + B.y);}Vector operator - (Point A, Point B){return Vector(A.x - B.x, A.y - B.y);}Vector operator * (Vector A, double p){return Vector(A.x * p, A.y * p);}Vector operator / (Vector A, double p){return Vector(A.x / p, A.y / p);}bool operator < (const Point& a, const Point& b){return a.x < b.x || (a.x == b.x && a.y < b.y);}const double eps = 1e-10;int dcmp(double x){if(fabs(x) < eps) return 0;else return x < 0 ? -1 : 1;}bool operator == (const Point& a, const Point& b){return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;}double Dot(Vector A, Vector B){return A.x * B.x + A.y * B.y;}double Length(Vector A){return sqrt(Dot(A, A));}double Angle(Vector A, Vector B){return acos(Dot(A, B) / Length(A) / Length(B));}double Cross(Vector A, Vector B){return A.x * B.y - A.y * B.x;}double Area2(Point A, Point B, Point C){return Cross(B - A, C - A);}double DistanceToSegment(Point P, Point A, Point B){if(A == B) return Length(P-A);Vector v1 = B - A, v2 = P - A, v3 = P - B;if(dcmp(Dot(v1, v2)) < 0) return Length(v2);else if(dcmp(Dot(v1, v3)) > 0) return Length(v3);else return fabs(Cross(v1, v2)) / Length(v1);}bool isPointOnSegment(Point p, Point a, Point b){if(b < a) swap(a, b);Vector v1 = b - a, v2 = p - a;return dcmp(Cross(v1, v2)) == 0 && (a < p || a == p) && (p < b || p == b);}int isPointInPolygon(Point p, Point* poly, int n){int wn = 0;for(int i = 0; i < n; i++){if(isPointOnSegment(p, poly[i], poly[(i+1)%n])) return -1;Vector v1 = poly[(i+1)%n] - poly[i], v2 = p - poly[i];int k = dcmp(Cross(poly[(i+1)%n]-poly[i], p-poly[i]));int d1 = dcmp(poly[i].y - p.y);int d2 = dcmp(poly[(i+1)%n].y - p.y);if(k > 0 && d1 <= 0 && d2 > 0) wn++;if(k < 0 && d2 <= 0 && d1 > 0) wn--;}if(wn != 0) return 1;else return 0;}//计算凸包,输入点数组p,个数为p,输出点数组ch。函数返回凸包顶点数。//输入不能有重复点。函数执行完之后输入点的顺序被破坏//如果不希望在凸包的边上有输入点,把两个 < 改成 <=//在精度要求高时建议用dcmp比较int ConvexHull(Point* p, int n, Point* ch){Point *p2 = new Point;for(int i = 0; i < n; i++) p2[i] = p[i];sort(p2, p2+n);int m = 0;for(int i = 0; i < n; i++){while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p2[i]-ch[m-2])) < 0) m--;ch[m++] = p2[i];}int k = m;for(int i = n-2; i >= 0; i--){while(m > k && dcmp(Cross(ch[m-1]-ch[m-2], p2[i]-ch[m-2])) < 0) m--;ch[m++] = p2[i];}if(n > 1) m--;return m;}bool isFill(Point p, double r, Point* poly, int n){for(int i = 0; i < n; i++){double d = DistanceToSegment(p, poly[i], poly[(i+1)%n]);if(d < r) return false;}return true;}int n;Point peg;double r;Point poly[maxn];Point ch[maxn];Point read_point(){double x, y;scanf("%lf%lf", &x, &y);return Point(x, y);}int main(){//FOP;while(~scanf("%d", &n) && n > 2){scanf("%lf", &r);peg = read_point();for(int i = 0; i < n; i++) poly[i] = read_point();if(ConvexHull(poly, n, ch) != n) printf("HOLE IS ILL-FORMED\n");else if(isPointInPolygon(peg, poly, n) != 1 || !isFill(peg, r, poly, n)) printf("PEG WILL NOT FIT\n");else printf("PEG WILL FIT\n");}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐