POJ3525-Most Distant Point from the Sea(二分+半平面交)
| Time Limit: 5000MS | Memory Limit: 65536K | |||
| Total Submissions: 3955 | Accepted: 1847 | 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 (xi, yi)–(xi+1, yi+1)
(1 ≤ i ≤ n − 1) and the line segment (xn, yn)–(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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define REP(_,a,b) for(int _ = (a); _ < (b); _++)
#define sz(s) (int)((s).size())
typedef long long ll;
const double eps = 1e-9;
const int maxn = 100*2+10;
struct Point{
double x,y;
Point(double x=0.0,double y = 0.0):x(x),y(y){}
};
vector<Point> vP;
typedef Point Vector;
Point poly[maxn];
vector<Vector> vV1,vV2;
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;
}
};
Line L[maxn];
Vector operator + (Vector A,Vector B) {
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator - (Vector A,Vector B){
return Vector(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);
}
bool operator < (const Point &a,const Point &b){
return a.x < b.x || (a.x==a.y && a.y < b.y);
}
int dcmp(double x){
if(fabs(x) < eps) return 0;
else return x < 0? -1:1;
}
bool operator == (const Point &a,const Point &b){
return dcmp(a.x-b.x)==0&& dcmp(a.y-b.y)==0;
}
double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;}
double Length(Vector A) {return sqrt(Dot(A,A));}
double Angle(Vector A,Vector B) {return acos(Dot(A,B)/Length(A)/Length(B));}
double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;}
Vector Rotate(Vector A,double rad) {return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); }
Vector Normal(Vector A) {
double L = Length(A);
return Vector(-A.y/L,A.x/L);
}
bool OnLeft(Line L,Point p){
return Cross(L.v,p-L.P) > 0;
}
Point GetIntersection(Line a,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;
}
int HalfplaneIntersection(Line* L,int n,Point* poly){
sort(L,L+n);
int first,last;
Point *p = new Point[n];
Line *q = new Line[n];
q[first=last=0] = L[0];
for(int 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] = GetIntersection(q[last-1],q[last]);
}
while(first < last && !OnLeft(q[first],p[last-1])) last--;
if(last - first <=1) return 0;
p[last] = GetIntersection(q[last],q[first]);
int m = 0;
for(int i = first; i <= last; i++) poly[m++] = p[i];
return m;
}
int n;
void init(){
vP.clear();
vV1.clear();
vV2.clear();
}
void input(){
REP(_,0,n){
double x,y;
scanf("%lf%lf",&x,&y);
vP.push_back(Point(x,y));
}
#define next(i) ((i)+1)%n
REP(_,0,n){
vV1.push_back(vP[next(_)]-vP[(_)]);
vV2.push_back(Normal(vP[next(_)]-vP[(_)]));
}
}
void solve(){
double l = 0,r = 40000;
while(r-l > eps){
double mid = (l+r)/2;
REP(_,0,n) {
L[_] = Line(vP[_]+vV2[_]*mid ,vV1[_]);
}
int m = HalfplaneIntersection(L,n,poly);
if(m==0){
r = mid;
}else{
l = mid;
}
}
printf("%.7f\n",r);
}
int main(){ while(~scanf("%d",&n) && n){
init();
input();
solve();
}
return 0;
}
POJ3525-Most Distant Point from the Sea(二分+半平面交)的更多相关文章
- poj3525Most Distant Point from the Sea(半平面交)
链接 求凸多边形内一点距离边最远. 做法:二分+半平面交判定. 二分距离,每次让每条边向内推进d,用半平面交判定一下是否有核. 本想自己写一个向内推进..仔细一看发现自己的平面交模板上自带.. #in ...
- 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 (半平面交向内推进+二分半径)
题目链接 题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少. 思路 :先二分半径r,半平面交向内推进r.模板题 #include <stdio.h> #include & ...
- 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 ...
- POJ 3525 Most Distant Point from the Sea 二分+半平面交
题目就是求多变形内部一点. 使得到任意边距离中的最小值最大. 那么我们想一下,可以发现其实求是看一个圆是否能放进这个多边形中. 那么我们就二分这个半径r,然后将多边形的每条边都往内退r距离. 求半平面 ...
- poj3525 Most Distant Point from the Sea
题目描述: vjudge POJ 题解: 二分答案+半平面交. 半径范围在0到5000之间二分,每次取$mid$然后平移所有直线,判断半平面交面积是否为零. 我的eps值取的是$10^{-12}$,3 ...
- poj 3525Most Distant Point from the Sea【二分+半平面交】
相当于多边形内最大圆,二分半径r,然后把每条边内收r,求是否有半平面交(即是否合法) #include<iostream> #include<cstdio> #include& ...
- UVa 1475 (二分+半平面交) Jungle Outpost
题意: 有n个瞭望塔构成一个凸n边形,敌人会炸毁一些瞭望台,剩下的瞭望台构成新的凸包.在凸多边形内部选择一个点作为总部,使得敌人需要炸毁的瞭望塔最多才能使总部暴露出来.输出敌人需要炸毁的数目. 分析: ...
- [HNOI2012][BZOJ2732] 射箭 [二分+半平面交]
题面 BZOJ题面 思路 半平面交代码讲解戳这里,用的就是这道题 我们射箭的函数形如$y=Ax^2+Bx$ 考虑每一个靶子$(x_0,y_1,y_2)$,实际上是关于$A,B$的不等式限制条件 我们只 ...
随机推荐
- 搜索引擎--范例:SAE创建新应用,SVN管理代码
最初接触的平台是新浪SAE平台,虽然限制多得要命,速度也不怎么样,但无论怎么样,人家是“免费的”,免费的东西你还想怎么样?是不是? 1:注册登录新浪SAE,这个不用多说,相信你们的智商 2:创建一个新 ...
- hdu 5188(带限制的01背包)
zhx and contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- springBoot 发布war包
1.packaging 改为war <packaging>war</packaging> 2.剔除内置tomcat <dependency> <groupId ...
- 大话PHP设计模式
设计模式 一书将设计模式引入软件社区,该书的作者是 Erich Gamma.Richard Helm.Ralph Johnson 和 John Vlissides Design(俗称 “四人帮”).所 ...
- Nodejs解决所有跨域请求
Nodejs解决所有跨域请求 app.use(function(req, res, next) { res.setHeader('Access-Control-Allow-Origin', '*'); ...
- Codeforces 853C - Boredom
853C - Boredom 题意 给出一个矩阵,每行每列有且仅有一个点.每次询问一个子矩形,问这些点构成的矩形有多少个与给定的矩形相交(两个处于对角线上的点可以组成矩形). 分析 考虑矩形周围 8 ...
- 树链剖分【p4114】Qtree-Query on a tree I
Description 给定一棵n个节点的树,有两个操作: CHANGE i ti 把第i条边的边权变成ti QUERY a b 输出从a到b的路径中最大的边权,当a=b的时候,输出0 Input 第 ...
- 进程注入后门工具Cymothoa
进程注入后门工具Cymothoa Cymothoa是一款隐秘的后门工具.它通过向目标主机活跃的进程注入恶意代码,从而获取和原进程相同的权限.该工具最大的优点就是不创建新的进程,不容易被发现.由于该 ...
- IntelliJ 常用设置
一.智能代码提示忽略大小写 打开设置(CTRL+ALT+S)搜索editor,找到“Code Completion”->点击Case sensitive completion后面的选择框,选中N ...
- Linux防止“rm -rf /”误删除
说明:不解释了,运维应该在每台服务器都去配置这个问题以减少灾难的发生 方法: 1.safe-rm safe-rm是一个开源软件用来替代不太安全的rm,可以在/etc/safe-rm.conf中配置路径 ...