POJ 3525 Most Distant Point from the Sea 二分+半平面交
题目就是求多变形内部一点。 使得到任意边距离中的最小值最大。
那么我们想一下,可以发现其实求是看一个圆是否能放进这个多边形中。
那么我们就二分这个半径r,然后将多边形的每条边都往内退r距离。
求半平面交看是否存在解即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <sstream>
#include <queue>
#include <vector>
#define MAXN 111111
#define MAXM 211111
#define PI acos(-1.0)
#define eps 1e-8
#define INF 1000000001
using namespace std;
int dblcmp(double d)
{
if (fabs(d) < eps) return 0;
return d > eps ? 1 : -1;
}
struct point
{
double x, y;
point(){}
point(double _x, double _y):
x(_x), y(_y){};
void input()
{
scanf("%lf%lf",&x, &y);
}
double dot(point p)
{
return x * p.x + y * p.y;
}
double distance(point p)
{
return hypot(x - p.x, y - p.y);
}
point sub(point p)
{
return point(x - p.x, y - p.y);
}
double det(point p)
{
return x * p.y - y * p.x;
}
bool operator == (point a)const
{
return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;
}
bool operator < (point a)const
{
return dblcmp(a.x - x) == 0 ? dblcmp(y - a.y) < 0 : x < a.x;
} }p[MAXN];
struct line
{
point a,b;
line(){}
line(point _a,point _b)
{
a=_a;
b=_b;
}
bool parallel(line v)
{
return dblcmp(b.sub(a).det(v.b.sub(v.a))) == 0;
}
point crosspoint(line v)
{
double a1 = v.b.sub(v.a).det(a.sub(v.a));
double a2 = v.b.sub(v.a).det(b.sub(v.a));
return point((a.x * a2 - b.x * a1) / (a2 - a1), (a.y * a2 - b.y * a1) / (a2 - a1));
}
bool operator == (line v)const
{
return (a == v.a) && (b == v.b);
}
};
struct halfplane:public line
{
double angle;
halfplane(){}
//表示向量 a->b逆时针(左侧)的半平面
halfplane(point _a, point _b)
{
a = _a;
b = _b;
}
halfplane(line v)
{
a = v.a;
b = v.b;
}
void calcangle()
{
angle = atan2(b.y - a.y, b.x - a.x);
}
bool operator <(const halfplane &b)const
{
return angle < b.angle;
}
};
struct polygon
{
int n;
point p[MAXN];
line l[MAXN];
double area;
void getline()
{
for (int i = 0; i < n; i++)
{
l[i] = line(p[i], p[(i + 1) % n]);
}
}
void getarea()
{
area = 0;
int a = 1, b = 2;
while(b <= n - 1)
{
area += p[a].sub(p[0]).det(p[b].sub(p[0]));
a++;
b++;
}
area = fabs(area) / 2;
}
}convex;
struct halfplanes
{
int n;
halfplane hp[MAXN];
point p[MAXN];
int que[MAXN];
int st, ed;
void push(halfplane tmp)
{
hp[n++] = tmp;
}
void unique()
{
int m = 1, i;
for (i = 1; i < n;i++)
{
if (dblcmp(hp[i].angle - hp[i - 1].angle))hp[m++] = hp[i];
else if (dblcmp(hp[m - 1].b.sub(hp[m - 1].a).det(hp[i].a.sub(hp[m - 1].a)) > 0))hp[m - 1] = hp[i];
}
n = m;
}
bool halfplaneinsert()
{
int i;
for (i = 0; i < n; i++) hp[i].calcangle();
sort(hp, hp + n);
unique();
que[st = 0] = 0;
que[ed = 1] = 1;
p[1] = hp[0].crosspoint(hp[1]);
for (i = 2; i < n; i++)
{
while (st < ed && dblcmp((hp[i].b.sub(hp[i].a).det(p[ed].sub(hp[i].a)))) < 0) ed--;
while (st < ed && dblcmp((hp[i].b.sub(hp[i].a).det(p[st + 1].sub(hp[i].a)))) < 0) st++;
que[++ed] = i;
if (hp[i].parallel(hp[que[ed - 1]])) return false;
p[ed] = hp[i].crosspoint(hp[que[ed - 1]]);
}
while (st < ed && dblcmp(hp[que[st]].b.sub(hp[que[st]].a).det(p[ed].sub(hp[que[st]].a))) < 0) ed--;
while (st < ed && dblcmp(hp[que[ed]].b.sub(hp[que[ed]].a).det(p[st + 1].sub(hp[que[ed]].a))) < 0) st++;
if (st + 1 >= ed)return false;
return true;
}
void getconvex(polygon &con)
{
p[st] = hp[que[st]].crosspoint(hp[que[ed]]);
con.n = ed - st + 1;
int j = st, i = 0;
for (; j <= ed; i++, j++)
{
con.p[i] = p[j];
}
}
}h;
int T;
int n;
line getmove(point a, point b, double mid)
{
double x = a.x - b.x;
double y = a.y - b.y;
double L = a.distance(b);
point ta = point(mid * y / L + a.x, a.y - mid * x / L);
point tb = point(mid * y / L + b.x, b.y - mid * x / L);
return line(ta, tb);
}
bool check(double mid)
{
h.n = 0;
for(int i = 0; i < n; i++)
{
line tmp = getmove(p[i], p[(i + 1) % n], mid);
h.push(halfplane(tmp));
}
return h.halfplaneinsert();
}
int main()
{
int cas = 0;
while(scanf("%d", &n) != EOF && n)
{
for(int i = 0; i < n; i++) p[i].input();
double low = 0, high = INF;
for(int i = 0; i < 100; i++)
{
double mid = (low + high) / 2;
if(check(mid)) low = mid;
else high = mid;
}
printf("%.6f\n", low);
}
return 0;
}
POJ 3525 Most Distant Point from the Sea 二分+半平面交的更多相关文章
- 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 [半平面交 二分]
Most Distant Point from the Sea Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5153 ...
- POJ 3525 Most Distant Point from the Sea (半平面交)
Description The main land of Japan called Honshu is an island surrounded by the sea. In such an isla ...
- POJ 3525 Most Distant Point from the Sea
http://poj.org/problem?id=3525 给出一个凸包,要求凸包内距离所有边的长度的最小值最大的是哪个 思路:二分答案,然后把凸包上的边移动这个距离,做半平面交看是否有解. #in ...
- POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)
题目链接 题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少. 思路 :先二分半径r,半平面交向内推进r.模板题 #include <stdio.h> #include & ...
- POJ 3130 How I Mathematician Wonder What You Are! /POJ 3335 Rotating Scoreboard 初涉半平面交
题意:逆时针给出N个点,求这个多边形是否有核. 思路:半平面交求多边形是否有核.模板题. 定义: 多边形核:多边形的核可以只是一个点,一条直线,但大多数情况下是一个区域(如果是一个区域则必为 ).核内 ...
- poj 3335 Rotating Scoreboard - 半平面交
/* poj 3335 Rotating Scoreboard - 半平面交 点是顺时针给出的 */ #include <stdio.h> #include<math.h> c ...
- poj 3384 半平面交
Feng Shui Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5183 Accepted: 1548 Speci ...
- POJ 2540 Hotter Colder --半平面交
题意: 一个(0,0)到(10,10)的矩形,目标点不定,从(0,0)开始走,如果走到新一点是"Hotter",那么意思是离目标点近了,如果是"Colder“,那么就是远 ...
随机推荐
- QThreadPool线程池的使用,线程与Widget通过信号与槽的方式通信。
因为QRunnable类并非继承自QObject,不能使用信号和槽,为了能够使用信号与槽和Widget通信,需要对QRunnable进行封装. 定义一个类QMyRunnable,该类首先继承自QObj ...
- 使用清华源和阿里源替代Ubuntu源
sudo nano /etc/apt/source.list 替换为如下文本 # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释 deb https://mirrors. ...
- logstash高速入口
原文地址:http://logstash.net/docs/1.4.2/tutorials/getting-started-with-logstash 英语水平有限,假设有错误请各位指正 简单介绍 L ...
- RabbitMQ简单使用
环境搭建: RabitMQ是用Elang编写的,虽然Elang本身是跨平台的,但也同时意味着搭建Rabit环境需要首先配置Elang环境.配置RabitMQ的网上教程还比较多的: windows 下 ...
- 【Go入门教程2】基本构成元素:标识符(identifier)、关键字(keyword 25个)、字面量(literal)、分隔符(delimiter)、和 操作符(operator)
基本构成要素 Go 的语言符号 又称 词法元素,共包括 5 类内容——标识符(identifier).关键字(keyword).字面量(literal).分隔符(delimiter) 和 操作符(op ...
- delphi TOnFormVisibleChangeEvent 事件应用
TGQIFileMgrForm = class(TForm) 定义 property OnVisibleChange: TOnFormVisibleChangeEvent read FOnVisibl ...
- AngularJS中自定义过滤器
AngularJS中为我们提供了一些内置的过滤器,这里列举一些自定义过滤器的场景. 自定义过滤器,不带参赛 //过滤 不带参赛 app.filter('ordinal', function () { ...
- AngularJS路由系列(2)--刷新、查看路由,路由事件和URL格式,获取路由参数,路由的Resolve
本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● 刷新路由● 查看当前路由以及所有路由● 路由触发事件● 获取路由参数 ● 路由的resolve属性● 路由URL格式 ...
- ASP.NET Web API实践系列11,如何设计出优秀的API
本篇摘自:InfoQ的微信公众号 在设计API的时候考虑的问题包括:API所使用的传输协议.支持的消息格式.接口的控制.名称.关联.次序,等等.我们很难始终作出正确的决策,很可能是在多次犯错之后,并从 ...
- Cesium中的地形和坐标转换说明
1 Cesium中的地形 Cesium中的地形系统是一种由流式瓦片数据生成地形mesh的技术,厉害指出在于其可以自动模拟出地面.海洋的三维效果.创建地形图层的方式如下: var terrainProv ...