题意:

给出一个凸n边形,求多边形内部一点使得该点到边的最小距离最大。

分析:

最小值最大可以用二分。

多边形每条边的左边是一个半平面,将这n个半平面向左移动距离x,则将这个凸多边形缩小了。如果这n个半平面交非空,则存在这样距离为x的点,反之则不存在。

半平面交的代码还没有完全理解。

和凸包类似,先对这些半平面进行极角排序。每次新加入的平面可能让队尾的平面变得“无用”,从而需要删除。由于极角序是环形的,所以也可能让队首元素变得“无用”。所以用双端队列来维护。

 //#define LOCAL
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std; const double eps = 1e-; struct Point
{
double x, y;
Point(double x=, double y=):x(x), y(y){}
};
typedef Point Vector;
Point operator + (Point A, Point B) { return Point(A.x+B.x, A.y+B.y); }
Point operator - (Point A, Point B) { return Point(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); }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
Vector Normal(Vector A) { double l = Length(A); return Vector(-A.y/l, A.x/l); } double PolygonArea(const vector<Point>& p)
{
double ans = 0.0;
int n = p.size();
for(int i = ; i < n-; ++i)
ans += Cross(p[i]-p[], p[i+]-p[]);
return ans/;
} struct Line
{
Point p;
Vector v;
double ang;
Line() {}
Line(Point p, Vector v):p(p), v(v) { ang = atan2(v.y, v.x); }
bool operator < (const Line& L) const
{
return ang < L.ang;
}
}; bool OnLeft(const Line& L, const Point& p)
{ return Cross(L.v, p-L.p) > ; } Point GetLineIntersection(const Line& a, const Line& b)
{
Vector u = a.p-b.p;
double t = Cross(b.v, u) / Cross(a.v, b.v);
return a.p + a.v*t;
} vector<Point> HalfplaneIntersection(vector<Line> L)
{
int n = L.size();
sort(L.begin(), L.end()); int first, last;
vector<Point> p(n);
vector<Line> q(n);
vector<Point> ans; q[first=last=] = L[];
for(int i = ; i < n; ++i)
{
while(first < last && !OnLeft(L[i], p[last-])) last--;
while(first < last && !OnLeft(L[i], p[first])) first++;
q[++last] = L[i];
if(fabs(Cross(q[last].v, q[last-].v)) < eps) //Èç¹ûÁ½Ö±Ï߯½ÐУ¬È¡ÄÚ²àµÄÄǸö
{
last--;
if(OnLeft(q[last], L[i].p)) q[last] = L[i];
}
if(first < last) p[last-] = GetLineIntersection(q[last-], q[last]);
}
while(first < last && !OnLeft(q[first], p[last-])) last--;
if(last - first <= ) return ans;
p[last] = GetLineIntersection(q[last], q[first]); for(int i = first; i <= last; ++i) ans.push_back(p[i]);
return ans;
} int main(void)
{
#ifdef LOCAL
freopen("3890in.txt", "r", stdin);
#endif int n;
while(scanf("%d", &n) == && n)
{
vector<Point> p, v, normal;
int m, x, y;
for(int i = ; i < n; ++i) { scanf("%d%d", &x, &y); p.push_back(Point(x, y)); }
if(PolygonArea(p) < ) reverse(p.begin(), p.end()); for(int i = ; i < n; ++i)
{
v.push_back(p[(i+)%n] - p[i]);
normal.push_back(Normal(v[i]));
} double left = , right = ;
while(right - left > 5e-)
{
vector<Line> L;
double mid = (right + left) / ;
for(int i = ; i < n; ++i) L.push_back(Line(p[i] + normal[i]*mid, v[i]));
vector<Point> Poly = HalfplaneIntersection(L);
if(Poly.empty()) right = mid;
else left = mid;
}
printf("%.6lf\n", left);
} return ;
}

代码君

LA 3890 (半平面交) Most Distant Point from the Sea的更多相关文章

  1. LA 2218 (半平面交) Triathlon

    题意: 有n个选手,铁人三项有连续的三段,对于每段场地选手i分别以vi, ui 和 wi匀速通过. 对于每个选手,问能否通过调整每种赛道的长度使得他成为冠军(不能并列). 分析: 粗一看,这不像一道计 ...

  2. LA 3890 Most Distant Point from the Sea(半平面交)

    Most Distant Point from the Sea [题目链接]Most Distant Point from the Sea [题目类型]半平面交 &题解: 蓝书279 二分答案 ...

  3. 简单几何(半平面交+二分) LA 3890 Most Distant Point from the Sea

    题目传送门 题意:凸多边形的小岛在海里,问岛上的点到海最远的距离. 分析:训练指南P279,二分答案,然后整个多边形往内部收缩,如果半平面交非空,那么这些点构成半平面,存在满足的点. /******* ...

  4. UVA 3890 Most Distant Point from the Sea(二分法+半平面交)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11358 [思路] 二分法+半平面交 二分与海边的的距离,由法向量可 ...

  5. POJ 3525 Most Distant Point from the Sea [半平面交 二分]

    Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5153   ...

  6. POJ 3525 Most Distant Point from the Sea (半平面交+二分)

    Most Distant Point from the Sea Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3476   ...

  7. 【POJ 3525】Most Distant Point from the Sea(直线平移、半平面交)

    按逆时针顺序给出n个点,求它们组成的多边形的最大内切圆半径. 二分这个半径,将所有直线向多边形中心平移r距离,如果半平面交不存在那么r大了,否则r小了. 平移直线就是对于向量ab,因为是逆时针的,向中 ...

  8. poj3525Most Distant Point from the Sea(半平面交)

    链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. #in ...

  9. POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)

    题目链接 题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少. 思路 :先二分半径r,半平面交向内推进r.模板题 #include <stdio.h> #include & ...

随机推荐

  1. SecureCRT配色方案

    SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件.作为一款经常使用的终端软件,一个好的配色方案可以大大的提高学 ...

  2. python 基于小顶堆实现随机抽样

    起因:之前用蓄水池抽样,算法精简,但直观性很差. 所以这次采用了简单的,为没一个行,赋值一个随机值,然后取 最大的K个作为,随机样本. 基本思路:为每一个行(record,记录,实体) 赋一个rand ...

  3. XCode签名证书死活不能选

    Editors>Show Values on Xcode , then you can select the code sign instead of typing

  4. 在线最优化求解(Online Optimization)之一:预备篇

    在线最优化求解(Online Optimization)之一:预备篇 动机与目的 在实际工作中,无论是工程师.项目经理.产品同学都会经常讨论一类话题:“从线上对比的效果来看,某某特征或因素对xx产品的 ...

  5. 【Unity--Apwork框架】AOP编程--拦截,用于缓存和异常处理(Unity框架的拦截注入-Interception)

    第一步:定义拦截行为:CachingBehavior 和 ExceptionLoggingBehavior 他们都继承接口:IInterceptionBehavior (程序集 Microsoft.P ...

  6. sp_MSforeachtable使用方法 查看库中所有表的空间大小

    sp_MSforeachtable使用方法 1)说明系统存储过程sp_MSforeachtable和sp_MSforeachdb,是微软提供的两个不公开的存储过程,从ms sql 6.5开始.存放在S ...

  7. POJ 1922

    #include<iostream>cheng da cai zi 11.21 //#include<stdio.h> #include<math.h> using ...

  8. Android SeekBar的OnSeekBarChangeListener

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { /** * 拖动中数值的时候 * @param f ...

  9. 初识spring与quartz整合实现定时任务

    参考资料: http://kevin19900306.iteye.com/blog/1397744 引用自别人的博客: 特别注意一点,与Spring3.1以下版本整合必须使用Quartz1,最初我拿2 ...

  10. KMP笔记√//找最大子串,前缀自匹配长度

    假设s1里找s2,然后s2进去匹配假设在第三位失配那么说明前两位是匹配成功的 如果这时候将s2后移一位相当于将s2的第一位和s2的第二位比较,如果我们已知s1(1)≠s1(2)那么就可以直接后移两位 ...