poj 1584 A Round Peg in a Ground Hole
来源:互联网 发布:php支付接口demo 编辑:程序博客网 时间:2024/05/21 09:15
题意:1.所有的点不能刚好能构成凸包输出:HOLE IS ILL-FORMED
2.否则如果圆不超出凸包输出:PEG WILL FIT,不然输出:PEG WILL NOT FIT
分析:先判断判断是不是凸包, 是凸包的情况下判断圆是否在凸包内(包括内切)。
判断凸包:获取凸包,如果最后顶点数和凸包顶点数不一样就不是。
判断圆是否在凸包内:判断圆心在凸包内,在则获取圆心到凸包边上的最小值。大于半径则不在。
判断圆心和凸包的关系:1.查看有向面积符号的一致性O(n)。2.二分极角判断O(log(n))。
2.否则如果圆不超出凸包输出:PEG WILL FIT,不然输出:PEG WILL NOT FIT
分析:先判断判断是不是凸包, 是凸包的情况下判断圆是否在凸包内(包括内切)。
判断凸包:获取凸包,如果最后顶点数和凸包顶点数不一样就不是。
判断圆是否在凸包内:判断圆心在凸包内,在则获取圆心到凸包边上的最小值。大于半径则不在。
判断圆心和凸包的关系:1.查看有向面积符号的一致性O(n)。2.二分极角判断O(log(n))。
#include<iostream>#include<cmath>#include<cstring>#include<cstdio>#include<string>#include <map>#include <vector>#include<algorithm>#include <complex>#define eps 1e-8#define INF 1e8using namespace std;typedef double TYPE;inline int sgn(double x){return x < -eps ? -1 : ( x > eps? 1 : 0);}struct Point{ TYPE x, y; Point(){} Point(const TYPE &xx, const TYPE &yy):x(xx), y(yy){} void input(){scanf("%lf %lf", &x, &y);} void output(){ printf("%.2f %.2f\n", x, y);} Point operator + (const Point &p)const{ return Point(x + p.x, y + p.y);} Point operator - (const Point &p)const{return Point(x- p.x, y - p.y);} Point operator / (const TYPE &w)const{return Point(x /w, y/w );} Point operator * (const TYPE &w)const{ return Point(x * w, y * w);} friend Point operator * (const TYPE &w, const Point &p){ return Point(w * p.x, w * p.y);} bool operator < (const Point &p)const{ return x < p.x || ( x == p.x && y < p.y);} friend double det(const Point &a, const Point &b){ return a.x* b.y - a.y * b.x;} friend double dot(const Point &a, const Point &b){return a.x * b.x + a.y* b.y;} double norm()const{ return sqrt(x * x + y * y);}};struct Line{ Point s, t; Line(){} Line(Point ss, Point tt):s(ss), t(tt){} double distPointToLine(const Point &p){ if(sgn(dot(t - s, p - s)) < 0)return (p - s).norm(); if(sgn(dot( s - t, p - t)) < 0)return (p - t).norm(); return (fabs(det(s - p, t - p))/ (s - t).norm()); }};struct Hull{ int n; vector<Point>v; Hull( ){ v.resize(0); } void getHull(vector<Point> &ps){ int tSize = ps.size(); v.resize(0); sort(ps.begin(), ps.end()); int m = 0; for(int i = 0; i < tSize; i++){ while(m > 1 && sgn(det(v[m - 1] - v[m - 2], ps[i] - v[m - 2])) < 0)m--, v.pop_back(); v.push_back(ps[i]); m++; } int k = m; for(int i = tSize - 2; i >= 0; i--){ while(m > k && sgn(det(v[m - 1] - v[m - 2], ps[i] - v[m - 2])) < 0 )m--, v.pop_back(); v.push_back(ps[i]); m++; } v.resize(m); if(m > 0)v.resize(m - 1);// for(int i = 0;i < v.size();i ++){// v[i].output();// } } bool isContain(const Point &t){ // 16MS过~ int sign = 0; int tSize = v.size(); for(int i = 0; i < tSize; i++){ if(sgn(det(t - v[i], t - v[(i + 1)%tSize])) == 0){ return true;}//边界上 } for(int i = 0; i < tSize; i++){ int tSign = sgn(det(v[(i + 1)%tSize] - t, v[i] - t)); if(tSign){ if(sign){ if(sign != tSign)return false;//外面 }else { sign = tSign; } } } return true;//内部 } //二分极角,Olog(n)版本判断点和凸包的位置关系, 0MS过,神奇! bool isContainOlogn(Point &t){ int n = v.size(), l = 0, r = n; Point g = (v[0] + v[n / 3] + v[n * 2/ 3])/3.0;//凸包内部一个点(其中一个三角形的重心); while(l + 1< r){ int mid = (r + l)>> 1; int k = sgn(det(v[l] - g, v[mid] - g)); int res1 = sgn(det(v[l] - g, t - g)); int res2 = sgn(det(v[mid] - g, t - g)); if(k > 0){ if(res1>= 0 && res2< 0){ r = mid; }else { l = mid; } }else { if(res1 < 0 &&res2 >=0 ){ l = mid; }else { r = mid; } } } r %= n; int res = sgn(det(v[r] - t, v[l] - t)); if(res == -1 || res == 0)return true; return false; }}hull;vector<Point>ps;Point co;double r;int n;void init(){ scanf("%lf", &r); co.input(); ps.resize(n); for(int i = 0; i < n; i++){ ps[i].input(); }}void solve(){ hull.getHull(ps); if(ps.size() != hull.v.size()){ puts("HOLE IS ILL-FORMED"); }else { if(hull.isContainOlogn(co)){ int tSize = hull.v.size(); double min_d = INF; for(int i = 0;i < tSize; i++){ Line line(hull.v[i], hull.v[(i+1)%tSize]); min_d = min(line.distPointToLine(co), min_d); } if(sgn(min_d - r) >= 0){ puts("PEG WILL FIT"); }else { puts("PEG WILL NOT FIT"); } }else { puts("PEG WILL NOT FIT"); } }}int main(){ while(scanf("%d", &n), n > 2){ init(); solve(); } return 0 ;}
- POJ 1584 A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole
- POJ 1584 A Round Peg in a Ground Hole
- POJ 1584 A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole
- POJ 1584--A Round Peg in a Ground Hole
- POJ 1584 A Round Peg in a Ground Hole
- A Round Peg in a Ground Hole - POJ 1584
- POJ 1584:A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole
- POJ 1584[A Round Peg in a Ground Hole]题解
- POJ 1584.A Round Peg in a Ground Hole
- A Round Peg in a Ground Hole
- poj1584A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole(判断凸多边形+圆是否在凸多边形内)
- POJ 1584 A Round Peg in a Ground Hole 圆是否包含在凸包内
- 百度地图API中,有GPS坐标转百度坐标的功能
- linux安装java jdk
- VS未能加载包的解决办法
- awk脚本学习小结
- 蓝烨:关注价值创造 助力企业发展_亿邦电商两会
- poj 1584 A Round Peg in a Ground Hole
- Eclipse开发环境搭建
- MD5加密 IOS
- arcgis java调用AE多波段合成实现
- Android中点击Button按钮或响应业务处理后如何隐藏输入法键盘
- UITableView学习笔记
- 连接数据库操作业务逻辑层
- hdu 3535 AreYouBusy(背包)
- ARM的BIN文件反汇编方法