Most Distant Point from the Sea
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 3640   Accepted: 1683   Special Judge

Description

The main land of Japan called Honshu is an island surrounded by the sea. In such an island, it is natural to ask a question: “Where is the most distant point from the sea?” The answer to this question for Honshu was found in 1996. The most distant point is located in former Usuda Town, Nagano Prefecture, whose distance from the sea is 114.86 km.

In this problem, you are asked to write a program which, given a map of an island, finds the most distant point from the sea in the island, and reports its distance from the sea. In order to simplify the problem, we only consider maps representable by convex polygons.

Input

The input consists of multiple datasets. Each dataset represents a map of an island, which is a convex polygon. The format of a dataset is as follows.

n    
x1   y1
   
xn   yn

Every input item in a dataset is a non-negative integer. Two input items in a line are separated by a space.

n in the first line is the number of vertices of the polygon, satisfying 3 ≤ n ≤ 100. Subsequent n lines are the x- and y-coordinates of the n vertices. Line segments (xiyi)–(xi+1yi+1) (1 ≤ i ≤ n − 1) and the line segment (xn,yn)–(x1y1) form the border of the polygon in counterclockwise order. That is, these line segments see the inside of the polygon in the left of their directions. All coordinate values are between 0 and 10000, inclusive.

You can assume that the polygon is simple, that is, its border never crosses or touches itself. As stated above, the given polygon is always a convex one.

The last dataset is followed by a line containing a single zero.

Output

For each dataset in the input, one line containing the distance of the most distant point from the sea should be output. An output line should not contain extra characters such as spaces. The answer should not have an error greater than 0.00001 (10−5). You may output any number of digits after the decimal point, provided that the above accuracy condition is satisfied.

Sample Input

4
0 0
10000 0
10000 10000
0 10000
3
0 0
10000 0
7000 1000
6
0 40
100 20
250 40
250 70
100 90
0 70
3
0 0
10000 10000
5000 5001
0

Sample Output

5000.000000
494.233641
34.542948
0.353553 题目大意:求凸包的最大内切圆
分析:二分找答案,对凸包的每条边平移收缩,若半平面交不为空集,则可以存在此半径的圆。
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std; struct Point {
double x, y;
Point(double x=0, double y=0):x(x),y(y) { }
}; typedef Point Vector; Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (const Point& A, const Point& B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (const Vector& A, double p) { return Vector(A.x*p, A.y*p); }
double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; }
double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; }
double Length(const Vector& A) { return sqrt(Dot(A, A)); }
Vector Normal(const Vector& A) { double L = Length(A); return Vector(-A.y/L, A.x/L); } double PolygonArea(vector<Point> p) {
int n = p.size();
double area = 0;
for(int i = 1; i < n-1; i++)
area += Cross(p[i]-p[0], p[i+1]-p[0]);
return area/2;
} // 有向直线。它的左边就是对应的半平面
struct Line {
Point P; // 直线上任意一点
Vector v; // 方向向量
double ang; // 极角,即从x正半轴旋转到向量v所需要的角(弧度)
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;
}
}; // 点p在有向直线L的左边(线上不算)
bool OnLeft(const Line& L, const Point& p) {
return Cross(L.v, p-L.P) > 0;
} // 二直线交点,假定交点惟一存在
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;
} const double eps = 1e-6; // 半平面交主过程
vector<Point> HalfplaneIntersection(vector<Line> L) {
int n = L.size();
sort(L.begin(), L.end()); // 按极角排序
int first, last,i; // 双端队列的第一个元素和最后一个元素的下标
vector<Point> p(n); // p[i]为q[i]和q[i+1]的交点
vector<Line> q(n); // 双端队列
vector<Point> ans; // 结果
q[first=last=0] = L[0]; // 双端队列初始化为只有一个半平面L[0]
for(i = 1; i < n; i++) {
while(first < last && !OnLeft(L[i], p[last-1])) last--;
while(first < last && !OnLeft(L[i], p[first])) first++;
q[++last] = L[i];
if(fabs(Cross(q[last].v, q[last-1].v)) < eps) { // 两向量平行且同向,取内侧的一个
last--;
if(OnLeft(q[last], L[i].P)) q[last] = L[i];
}
if(first < last) p[last-1] = GetLineIntersection(q[last-1], q[last]);
}
while(first < last && !OnLeft(q[first], p[last-1])) last--; // 删除无用平面
if(last - first <= 1) return ans; // 空集
p[last] = GetLineIntersection(q[last], q[first]); // 计算首尾两个半平面的交点
// 从deque复制到输出中
for(i = first; i <= last; i++) ans.push_back(p[i]);
return ans;
} int main() {
int n;
while(scanf("%d", &n) == 1 && n)
{
vector<Vector> p, v, normal;
int i, x, y;
for(i = 0; i < n; i++) { scanf("%d%d", &x, &y); p.push_back(Point(x,y)); }
for(i = 0; i < n; i++) {
v.push_back(p[(i+1)%n]-p[i]);
normal.push_back(Normal(v[i]));
} double left = 0, right = 20000;
while(right-left > 1e-6)
{
vector<Line> L;
double mid = left+(right-left)/2;
for(i = 0; 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 0;
}

poj 3525 求凸包的最大内切圆的更多相关文章

  1. POJ 2187 求凸包上最长距离

    简单的旋转卡壳题目 以每一条边作为基础,找到那个最远的对踵点,计算所有对踵点的点对距离 这里求的是距离的平方,所有过程都是int即可 #include <iostream> #includ ...

  2. 计算几何--求凸包模板--Graham算法--poj 1113

    Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28157   Accepted: 9401 Description ...

  3. poj 1113:Wall(计算几何,求凸包周长)

    Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28462   Accepted: 9498 Description ...

  4. POJ 3348 Cows 凸包 求面积

    LINK 题意:给出点集,求凸包的面积 思路:主要是求面积的考察,固定一个点顺序枚举两个点叉积求三角形面积和除2即可 /** @Date : 2017-07-19 16:07:11 * @FileNa ...

  5. POJ 2187 Beauty Contest【旋转卡壳求凸包直径】

    链接: http://poj.org/problem?id=2187 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  6. 简单几何(求凸包点数) POJ 1228 Grandpa's Estate

    题目传送门 题意:判断一些点的凸包能否唯一确定 分析:如果凸包边上没有其他点,那么边想象成橡皮筋,可以往外拖动,这不是唯一确定的.还有求凸包的点数<=2的情况一定不能确定. /********* ...

  7. POJ 1113 Wall(Graham求凸包周长)

    题目链接 题意 : 求凸包周长+一个完整的圆周长. 因为走一圈,经过拐点时,所形成的扇形的内角和是360度,故一个完整的圆. 思路 : 求出凸包来,然后加上圆的周长 #include <stdi ...

  8. POJ 1113 Wall 凸包求周长

    Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26286   Accepted: 8760 Description ...

  9. Wall - POJ 1113(求凸包)

    题目大意:给N个点,然后要修建一个围墙把所有的点都包裹起来,但是要求围墙距离所有的点的最小距离是L,求出来围墙的长度. 分析:如果没有最小距离这个条件那么很容易看出来是一个凸包,然后在加上一个最小距离 ...

随机推荐

  1. codevs 1313 质因数分解

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题目描述 Description 已知正整数 n是两个不同的质数的乘积,试求出较大的那个质数 . 输入描述 I ...

  2. 霍金的新语音系统 ACAT 将开源

    英国理论物理学家斯蒂芬·霍金(Stephen Hawking)使用了二十年的语音通讯系统被英特尔开发的新一代通讯平台替代,显著改进了通讯效率.但霍金的声音并没有发生改变,他仍然使用相同的语音合成器.霍 ...

  3. 小白安装python软件

    首先下载:anaconda3.x          下载方式:百度搜索 清华镜像anaconda   https://mirrors.tuna.tsinghua.edu.cn/help/anacond ...

  4. win7旗舰版下配置IIS服务器

    选择上述的插件后,Windows 需要更新一段时间,并重启电脑 测试是否安装成功:http://localhost       注意:默认端口号是 80,不能和tomcat 的 80 端口同时重启 常 ...

  5. Window命令行杀进程

    Window命令行杀进程 1.查看任务列表 tasklist 2.以映象名杀 taskkill -t -f -im xx.exe 3.以进程杀死 taskkill /pid pid号 /f 4.针对w ...

  6. java在线聊天项目0.9版 实现把服务端接收到的信息返回给每一个客户端窗口中显示功能之客户端接收

    客户端要不断接收服务端发来的信息 与服务端不断接收客户端发来信息相同,使用线程的方法,在线程中循环接收 客户端修改后代码如下: package com.swift; import java.awt.B ...

  7. 牛客练习赛40 C-小A与欧拉路

    求图中最短的欧拉路.题解:因为是一棵树,因此当从某一个节点遍历其子树的时候,如果还没有遍历完整个树,一定还需要再回到这个节点再去遍历其它子树,因此除了从起点到终点之间的路,其它路都被走了两次,而我们要 ...

  8. windowsServer2008搭建域服务器

    为什么要搭建域? 工作组的分散管理模式不适合大型的网络环境下工作,域模式就是针对大型的网络管理需求设计的,就是共享用户账号,计算机账号和安全策略的计算机集合.域中集中存储用户账号的计算机就是域控器,域 ...

  9. Memcached特性及优缺点

    为了加快文件访问速度且提供多个使用者.需要在内存中建立内存缓存数据的管理减小读写磁盘的次数及保证数据的更新.因为需要使用cache缓存.   1.Memcached 主要特性 a.数据仅存在于内存中, ...

  10. 电子邮件中的to、cc、bcc

    电子邮件中的to.cc(carbon copy)和bcc(blind carbon copy),分别是收件人.抄送.密送 to 收件人 你想要给其发邮件的人 cc 抄送人 cc和to是一样的,但是cc ...