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.

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+1, yi+1) (1 ≤ i ≤ n − 1) and the line segment (xnyn)–(x1, y1) 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

题意: 按逆时针给出一个凸多边形,求最大的内切圆半径。

分析: 如果能想到二分半径,那这道题会容易很多。可以想象一下,如果半径为r的圆完全在多边形内部,那么各边向内平移r个距离得到的还是一个凸多边形,如果半径为r的圆不能被完全放入多边形内,那么各边向内平移r个距离构不成多边形。因此可以二分半径。对于一个确定的半径只需要判断是否可以被完全包含在凸多边形内部,具体判断的过程需要用到半平面交,显然凸多边形的半平面交为它自身,如果平移过后还是一个凸多边形,那它的半平面交一定存在,如果无法构成多边形,那半平面交也一定不存在,可以利用这个性质来写check。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
int sgn(double x)
{if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}
struct Point
{double x, y;Point(){}Point(double _x,double _y){x = _x, y = _y;}void input(){scanf("%lf%lf",&x,&y);}void output(){printf("%.2f %.2f\n",x,y);}bool operator == (Point b)const{return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;}bool operator < (Point b)const{return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x;}//点积double operator *(const Point &b)const{return x*b.x + y*b.y;}//返回长度double len(){return hypot(x,y);/*库函数*/}//返回长度的平方double len2(){return x*x + y*y;}//返回两点的距离double distance(Point p){return hypot(x-p.x,y-p.y);}Point operator +(const Point &b)const{return Point(x+b.x,y+b.y);}Point operator *(const double &k)const{return Point(x*k,y*k);}Point operator /(const double &k)const{return Point(x/k,y/k);}
};
struct Line
{Point s,e;Line(){}Line(Point _s,Point _e){s = _s, e = _e;}bool operator ==(Line v){return (s == v.s)&&(e == v.e);}//`根据一个点和倾斜角angle确定直线,0<=angle<pi`Line(Point p,double angle){s = p;if(sgn(angle-pi/2) == 0){e = (s + Point(0,1));}else{e = (s + Point(1,tan(angle)));}}double length(){return s.distance(e);}void input(){s.input();e.input();}bool parallel(Line v){return sgn((e-s)^(v.e-v.s)) == 0;/*两向量叉积为0*/ }Point crosspoint(Line v){double a1 = (v.e-v.s)^(s-v.s);double a2 = (v.e-v.s)^(e-v.s);return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));}
};
struct halfplane:public Line
{double angle;halfplane(){}//`表示向量s->e逆时针(左侧)的半平面`halfplane(Point _s,Point _e){s = _s;e = _e;}halfplane(Line v){s = v.s;e = v.e;}void calcangle(){angle = atan2(e.y-s.y,e.x-s.x);}bool operator <(const halfplane &b)const{return angle < b.angle;}
};struct halfplanes
{int n;//需要输入 halfplane hp[maxp];//需要输入,且封闭区域都在向量逆时针方向 Point p[maxp];int que[maxp];int st,ed;//队列的头尾指针,且下标从0开始,指向元素就是头和尾 void push(halfplane tmp){hp[n++] = tmp;}//去重void unique(){int m = 1;for(int i = 1;i < n;i++){if(sgn(hp[i].angle-hp[i-1].angle) != 0)hp[m++] = hp[i];//去除极角相同的情况下,位置在右边(沿向量方向)的边 else if(sgn( (hp[m-1].e-hp[m-1].s)^(hp[i].s-hp[m-1].s) ) > 0)hp[m-1] = hp[i];}n = m;}bool halfplaneinsert()//判断半平面交是否存在 {for(int 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(int i = 2;i < n;i++){while(st<ed && sgn((hp[i].e-hp[i].s)^(p[ed]-hp[i].s))<0)ed--;while(st<ed && sgn((hp[i].e-hp[i].s)^(p[st+1]-hp[i].s))<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 && sgn((hp[que[st]].e-hp[que[st]].s)^(p[ed]-hp[que[st]].s))<0)ed--;while(st<ed && sgn((hp[que[ed]].e-hp[que[ed]].s)^(p[st+1]-hp[que[ed]].s))<0)st++;if(st+1>=ed)return false;//最后剩下小于三条直线,表明半平面交不存在 return true;}
};signed main()
{int n;while(~scanf("%d", &n)){if(n == 0)break;Point p[maxp];for(int i = 0; i < n; i++)p[i].input();halfplanes a;a.n = 0;for(int i = 0; i < n; i++){halfplane temp(p[i], p[(i+1)%n]);a.push(temp);}double l = 0.0, r = 5e3+300;while(r-l > eps){double mid = (l+r)/2;for(int i = 0; i < n; i++){Point vec = p[(i+1)%n]-p[i];vec = Point(-vec.y/vec.len(), vec.x/vec.len());halfplane temp(p[i]+vec*mid, p[(i+1)%n]+vec*mid);//向内平移mid长度 a.hp[i] = temp;}if(a.halfplaneinsert())l = mid;elser = mid;}printf("%.6f\n", l);}return 0;
}

[凸多边形最大内切圆][半平面交]Most Distant Point from the Sea POJ3525相关推荐

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

    题意: 给出一个凸n边形,求多边形内部一点使得该点到边的最小距离最大. 分析: 最小值最大可以用二分. 多边形每条边的左边是一个半平面,将这n个半平面向左移动距离x,则将这个凸多边形缩小了.如果这n个 ...

  2. UVA1396 Most Distant Point from the Sea(AM - ICPC - Tokyo - 2007)(计算几何,半平面交 + 二分答案)

    整理的算法模板合集: ACM模板 题目传送门 见<训练指南>P279 很明显就是一个二分答案,它问的是最远的点,直接枚举因为这里都是double类型的数所以有无限个点,我们可以直接二分. ...

  3. P4196-[CQOI2006]凸多边形/[模板]半平面交【计算几何】

    正题 题目链接:https://www.luogu.com.cn/problem/P4196 题目大意 给出nnn个凸多边形,求它们交的面积. 解题思路 就是把凸多边形上每条边作为一个半平面限制然后求 ...

  4. 【BZOJ-2618】凸多边形 计算几何 + 半平面交 + 增量法 + 三角剖分

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 959  Solved: 489 [Submit][Statu ...

  5. POJ 3525/UVA 1396 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 ...

  6. POJ 3525(计算几何+凸多边形最大内切圆)

    问题描述: The main land of Japan called Honshu is an island surrounded by the sea. In such an island, it ...

  7. 半平面交练习(计算几何)

    四:半平面交 Rotating Scoreboard /*Author : lifehappy */ #include <cstdio> #include <cmath> #i ...

  8. 模板:半平面交(计算几何)

    所谓半平面交,就是和"半平先生"当面交谈.顾名思义,这是一个源于日本的算法. (逃) 前言 感觉应用很灵活的一个算法,一切有两个变量的线性规划问题都可以转化为半平面交. 有时可能要 ...

  9. POJ 3384 Feng Shui(半平面交)

    题意 : 给你一个凸多边形,让你在其中找两个圆,使得圆的覆盖面积最大. 这个题目和 poj 3525 有点类似,那个题目是一个圆,想到两者的联系,可以发现两个圆覆盖面积最大就是重叠面积最小,怎样使得重 ...

最新文章

  1. 如何把Windows安装的所有打印机列出来
  2. Kmeans聚类定义、KMeans聚类的步骤、Kmeans聚类常见问题及改进、Kmeans聚类的变形、Kmeans聚类的优缺点
  3. 英语单词 factor cull
  4. [optee]-opteeTA启动的过程(open_ta的过程)
  5. html左侧td字体居右,如何在td中控制字体右对齐 且加粗_html/css_WEB-ITnose
  6. mysql-数据库的增删切换使用等操作
  7. 详细解读Python 递归函数!
  8. Error generating final archive: Debug Certificate expired on 的错误解决方法
  9. HTML DOM addEventListener()
  10. 3D中的相机 - 投影矩阵和视图矩阵
  11. Leetcode每日一题:649.dota2-senate(Dota2参议院)
  12. SQL Sever 数据完整性
  13. cupp字典生成工具(同类工具还有crunch)
  14. Linux查看网卡是千兆还是万兆网卡
  15. oracle驱动包下载
  16. 中国的Palantir诞生,开启大数据关联挖掘的新时代
  17. 存在外键关联的主表truncate如何做
  18. 蒙特卡洛树搜索(MCTS)的实例代码
  19. 【条形码识别】基于计算机视觉实现二维条形码识别含Matlab源码
  20. js 拖拽元素 鼠标速度过快问题

热门文章

  1. 第8章 泛型 《Kotlin 项目实战开发》
  2. 激光雷达赛道“白刃战”?硅光芯片级FMCW技术进入量产周期
  3. 那些年我们错过的markdown
  4. 2018-10-29 直播课笔记
  5. springboot2 整合 rocketmq
  6. 唯样商城:从黑暗到光明,LED照明演变史知多少?内有彩蛋
  7. Android 11.0 根据包名授予WRITE_SETTINGS权限
  8. web网络知识(一)公网IP、内网IP
  9. 买外链要多少钱?外链要去哪里买?
  10. 京东一键自动领取京豆、全自动签到、农场浇水、超市兑奖