LA 3890 (半平面交) Most Distant Point from the Sea
题意:
给出一个凸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的更多相关文章
- LA 2218 (半平面交) Triathlon
题意: 有n个选手,铁人三项有连续的三段,对于每段场地选手i分别以vi, ui 和 wi匀速通过. 对于每个选手,问能否通过调整每种赛道的长度使得他成为冠军(不能并列). 分析: 粗一看,这不像一道计 ...
- LA 3890 Most Distant Point from the Sea(半平面交)
Most Distant Point from the Sea [题目链接]Most Distant Point from the Sea [题目类型]半平面交 &题解: 蓝书279 二分答案 ...
- 简单几何(半平面交+二分) LA 3890 Most Distant Point from the Sea
题目传送门 题意:凸多边形的小岛在海里,问岛上的点到海最远的距离. 分析:训练指南P279,二分答案,然后整个多边形往内部收缩,如果半平面交非空,那么这些点构成半平面,存在满足的点. /******* ...
- UVA 3890 Most Distant Point from the Sea(二分法+半平面交)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11358 [思路] 二分法+半平面交 二分与海边的的距离,由法向量可 ...
- POJ 3525 Most Distant Point from the Sea [半平面交 二分]
Most Distant Point from the Sea Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5153 ...
- POJ 3525 Most Distant Point from the Sea (半平面交+二分)
Most Distant Point from the Sea Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3476 ...
- 【POJ 3525】Most Distant Point from the Sea(直线平移、半平面交)
按逆时针顺序给出n个点,求它们组成的多边形的最大内切圆半径. 二分这个半径,将所有直线向多边形中心平移r距离,如果半平面交不存在那么r大了,否则r小了. 平移直线就是对于向量ab,因为是逆时针的,向中 ...
- poj3525Most Distant Point from the Sea(半平面交)
链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. #in ...
- POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)
题目链接 题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少. 思路 :先二分半径r,半平面交向内推进r.模板题 #include <stdio.h> #include & ...
随机推荐
- Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D. Little Artem and Dance
题目链接: http://codeforces.com/contest/669/problem/D 题意: 给你一个初始序列:1,2,3,...,n. 现在有两种操作: 1.循环左移,循环右移. 2. ...
- Window7中Eclipse运行MapReduce程序报错的问题
按照文档:http://www.micmiu.com/bigdata/hadoop/hadoop2x-eclipse-mapreduce-demo/安装配置好Eclipse后,运行WordCount程 ...
- 不安装Oracle客户端远程连接Orcale数据库
本方法是通过使用ORACLE官方提供的精简版客户端,即绿色免安装的客户端. 下载地址(此处提供的是官方各版本下载地址): Windows 32位系统中使用的客户端下载地址其他系统环境中使用的客户端下载 ...
- [C/CPP系列知识] C++中extern “C” name mangling -- Name Mangling and extern “C” in C++
http://www.geeksforgeeks.org/extern-c-in-c/ C++函数重载(function overloading),但是C++编译器是如何区分不同的函数的呢?----是 ...
- uva 11235
数据结构 RMQ算法 左右左右 写得有点晕了 ..... /****************************************************************** ...
- POJ3414Pots
http://poj.org/problem?id=3414 题意 : 大意是说给你两个杯子的体积和一个目标体积,a,b,c,通过对a,b进行6种操作,调出c体积的水,6种操作分别是把a倒满,把b倒满 ...
- SDUT1574组合数的计算(组合数)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1574 这个题,比较奇怪,是用递推去做的,我试了 ...
- mac 下周期调度命令或脚本
crontab 是在linux服务器上部署定时任务的方法 0 5 * * * /usr/bin/python /data/www/tools/mysql_backup.py cmd之前有5个项目要填, ...
- lintcode 中等题:N Queens II N皇后问题 II
题目: N皇后问题 II 根据n皇后问题,现在返回n皇后不同的解决方案的数量而不是具体的放置布局. 样例 比如n=4,存在2种解决方案 解题: 和上一题差不多,这里只是求数量,这个题目定义全局变量,递 ...
- HTML5入门1---Canvas画布
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...