地址:http://codeforces.com/contest/801/problem/D

题目:

D. Volatile Kite
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a convex polygon P with n distinct vertices p1, p2, ..., pn. Vertex pi has coordinates (xi, yi) in the 2D plane. These vertices are listed in clockwise order.

You can choose a real number D and move each vertex of the polygon a distance of at most D from their original positions.

Find the maximum value of D such that no matter how you move the vertices, the polygon does not intersect itself and stays convex.

Input

The first line has one integer n (4 ≤ n ≤ 1 000) — the number of vertices.

The next n lines contain the coordinates of the vertices. Line i contains two integers xi and yi ( - 109 ≤ xi, yi ≤ 109) — the coordinates of the i-th vertex. These points are guaranteed to be given in clockwise order, and will form a strictly convex polygon (in particular, no three consecutive points lie on the same straight line).

Output

Print one real number D, which is the maximum real number such that no matter how you move the vertices, the polygon stays convex.

Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Namely, let's assume that your answer is a and the answer of the jury is b. The checker program will consider your answer correct if .

Examples
input
4
0 0
0 1
1 1
1 0
output
0.3535533906
input
6
5 0
10 0
12 -4
10 -8
5 -8
3 -4
output
1.0000000000
Note

Here is a picture of the first sample

Here is an example of making the polygon non-convex.

This is not an optimal solution, since the maximum distance we moved one point is  ≈ 0.4242640687, whereas we can make it non-convex by only moving each point a distance of at most  ≈ 0.3535533906.

思路:这题看起来很复杂,但是看下样例一的图后会发现一个结论:

  在相邻的三个点a,b,c中,能移动的最大距离d就是b到直线ac的距离的一半。

  证明:当d大于一半时,凸包会被破坏。

     当d小于一半时,凸包仍然存在(即可以继续移动)

  

  所以贴个求点到直线的模板,然后扫一遍所有点,求出所有可移动距离的最大值中的最小值即可。

  (完整代码模板我博客有

 #include <bits/stdc++.h>

 using namespace std;

 #define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int,int> PII;
const double eps=1e-;
const double pi=acos(-1.0);
const int K=1e6+;
const int mod=1e9+; //点
class Point
{
public:
double x, y; Point(){}
Point(double x, double y):x(x),y(y){} bool operator < (const Point &_se) const
{
return x<_se.x || (x==_se.x && y<_se.y);
}
/*******判断ta与tb的大小关系*******/
static int sgn(double ta,double tb)
{
if(fabs(ta-tb)<eps)return ;
if(ta<tb) return -;
return ;
}
static double xmult(const Point &po, const Point &ps, const Point &pe)
{
return (ps.x - po.x) * (pe.y - po.y) - (pe.x - po.x) * (ps.y - po.y);
}
friend Point operator + (const Point &_st,const Point &_se)
{
return Point(_st.x + _se.x, _st.y + _se.y);
}
friend Point operator - (const Point &_st,const Point &_se)
{
return Point(_st.x - _se.x, _st.y - _se.y);
}
//点位置相同(double类型)
bool operator == (const Point &_off) const
{
return Point::sgn(x, _off.x) == && Point::sgn(y, _off.y) == ;
}
//点位置不同(double类型)
bool operator != (const Point &_Off) const
{
return ((*this) == _Off) == false;
}
//两点间距离的平方
static double dis2(const Point &_st,const Point &_se)
{
return (_st.x - _se.x) * (_st.x - _se.x) + (_st.y - _se.y) * (_st.y - _se.y);
}
//两点间距离
static double dis(const Point &_st, const Point &_se)
{
return sqrt((_st.x - _se.x) * (_st.x - _se.x) + (_st.y - _se.y) * (_st.y - _se.y));
}
};
//两点表示的向量
class Line
{
public:
Point s, e;//两点表示,起点[s],终点[e]
double a, b, c;//一般式,ax+by+c=0 Line(){}
Line(const Point &s, const Point &e):s(s),e(e){}
Line(double _a,double _b,double _c):a(_a),b(_b),c(_c){} //向量与点的叉乘,参数:点[_Off]
//[点相对向量位置判断]
double operator /(const Point &_Off) const
{
return (_Off.y - s.y) * (e.x - s.x) - (_Off.x - s.x) * (e.y - s.y);
}
//向量与向量的叉乘,参数:向量[_Off]
friend double operator /(const Line &_st,const Line &_se)
{
return (_st.e.x - _st.s.x) * (_se.e.y - _se.s.y) - (_st.e.y - _st.s.y) * (_se.e.x - _se.s.x);
}
friend double operator *(const Line &_st,const Line &_se)
{
return (_st.e.x - _st.s.x) * (_se.e.x - _se.s.x) - (_st.e.y - _st.s.y) * (_se.e.y - _se.s.y);
}
//从两点表示转换为一般表示
//a=y2-y1,b=x1-x2,c=x2*y1-x1*y2
bool pton()
{
a = e.y - s.y;
b = s.x - e.x;
c = e.x * s.y - e.y * s.x;
return true;
} //-----------点和直线(向量)-----------
//点在向量左边(右边的小于号改成大于号即可,在对应直线上则加上=号)
//参数:点[_Off],向量[_Ori]
friend bool operator<(const Point &_Off, const Line &_Ori)
{
return (_Ori.e.y - _Ori.s.y) * (_Off.x - _Ori.s.x)
< (_Off.y - _Ori.s.y) * (_Ori.e.x - _Ori.s.x);
} //点在直线上,参数:点[_Off]
bool lhas(const Point &_Off) const
{
return Point::sgn((*this) / _Off, ) == ;
}
//点在线段上,参数:点[_Off]
bool shas(const Point &_Off) const
{
return lhas(_Off)
&& Point::sgn(_Off.x - min(s.x, e.x), ) > && Point::sgn(_Off.x - max(s.x, e.x), ) <
&& Point::sgn(_Off.y - min(s.y, e.y), ) > && Point::sgn(_Off.y - max(s.y, e.y), ) < ;
} //点到直线/线段的距离
//参数: 点[_Off], 是否是线段[isSegment](默认为直线)
double dis(const Point &_Off, bool isSegment = false)
{
///化为一般式
pton(); //到直线垂足的距离
double td = (a * _Off.x + b * _Off.y + c) / sqrt(a * a + b * b); //如果是线段判断垂足
if(isSegment)
{
double xp = (b * b * _Off.x - a * b * _Off.y - a * c) / ( a * a + b * b);
double yp = (-a * b * _Off.x + a * a * _Off.y - b * c) / (a * a + b * b);
double xb = max(s.x, e.x);
double yb = max(s.y, e.y);
double xs = s.x + e.x - xb;
double ys = s.y + e.y - yb;
if(xp > xb + eps || xp < xs - eps || yp > yb + eps || yp < ys - eps)
td = min(Point::dis(_Off,s), Point::dis(_Off,e));
} return fabs(td);
}
}; int n;
Point pt[K];
Line ta;
double ans=1e10;
int main(void)
{
cin>>n;
for(int i=;i<=n;i++)
scanf("%lf%lf",&pt[i].x,&pt[i].y);
for(int i=;i<=;i++)
pt[i+n]=pt[i];
for(int i=;i<=n;i++)
{
ta.s=pt[i],ta.e=pt[i+];
ans=min(ans,ta.dis(pt[i+])/2.0);
}
printf("%.8f\n",ans);
return ;
}

Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2) D. Volatile Kite的更多相关文章

  1. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)(A.思维题,B.思维题)

    A. Vicious Keyboard time limit per test:2 seconds memory limit per test:256 megabytes input:standard ...

  2. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2) C Voltage Keepsake

    地址:http://codeforces.com/contest/801/problem/C 题目: C. Voltage Keepsake time limit per test 2 seconds ...

  3. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2) 题解【ABCDE】

    A. Vicious Keyboard 题意:给你一个字符串,里面只会包含VK,这两种字符,然后你可以改变一个字符,你要求VK这个字串出现的次数最多. 题解:数据范围很小,暴力枚举改变哪个字符,然后c ...

  4. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2)

    A 每次可以换一个或不换,暴力枚举位置即可 B 模拟 C 二分答案.. 边界可以优化r=totb/(tota-p),二分可以直接(r-l>=EPS,EPS不要太小,合适就好),也可以直接限定二分 ...

  5. Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2) A B C D 暴力 水 二分 几何

    A. Vicious Keyboard time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 菜鸡只会ABC!

    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 全场题解 菜鸡只会A+B+C,呈上题解: A. Bear and ...

  7. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) C. Bear and Different Names 贪心

    C. Bear and Different Names 题目连接: http://codeforces.com/contest/791/problem/C Description In the arm ...

  8. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) B - Bear and Friendship Condition 水题

    B. Bear and Friendship Condition 题目连接: http://codeforces.com/contest/791/problem/B Description Bear ...

  9. 【树形dp】Codeforces Round #405 (rated, Div. 1, based on VK Cup 2017 Round 1) B. Bear and Tree Jumps

    我们要统计的答案是sigma([L/K]),L为路径的长度,中括号表示上取整. [L/K]化简一下就是(L+f(L,K))/K,f(L,K)表示长度为L的路径要想达到K的整数倍,还要加上多少. 于是, ...

随机推荐

  1. 怎样使用DWZ?

    首先说明,这篇文章不是解说DWZ内部实现原理的,也不打算分析它的源代码,这里仅仅是演示一下,怎样将DWZ框架整合到项目中去. 刚刚过去的项目中,前台UI使用的是DWZ.因为之前项目的开发环境都已经搭建 ...

  2. 系统管理模块_用户管理1_实现用户有关的功能_测试功能、解决事务的问题、对密码进行MD5摘要

    系统管理模块__用户管理1__实现用户有关的功能 了解用户管理要做什么(增删改查初始化密码) 设计实体 分析功能有几个对应几个请求 增删改查有6个请求,初始化密码一个 实现增删改查一组功能的步骤流程 ...

  3. Oracle自定义聚集函数

    今天工作中看见别人写的自定义聚集函数,所以一门心思的想搞懂,就在网上找资料了. 自定义聚集函数 自定义聚集函数接口简介 Oracle提供了很多预定义好的聚集函数,比如Max(), Sum(), AVG ...

  4. 将UIView转成UIImage,将UIImage转成PNG/JPG

    分类: UIImageView2013-03-12 17:37 350人阅读 评论(0) 收藏 举报 //UIView -> UIImage #import “QuartzCore/Quartz ...

  5. c++与js脚本交互,C++调用JS函数/JS调用C++函数

    <!DOCTYPE html> <html> <body> <h1>我的第一段 JavaScript</h1> <p> Java ...

  6. 《从零开始学Swift》学习笔记(Day 64)——Cocoa Touch设计模式及应用之目标与动作

    原创文章,欢迎转载.转载请注明:关东升的博客 目标(Target)与动作(Action)是iOS和OS X应用开发的中事件处理机制.   问题提出 如图所示是一个ButtonLabelSample案例 ...

  7. LAMP集群项目三 配置业务服务器

    安装MySQL 参考脚本:CentOS6.5一键安装MySQL5.5.32(源码编译) 在备份服务器上配置rsync推送任务 在备份服务器上配置  /etc/rsyncd.conf #在所有的客户端都 ...

  8. Servlet------>response

    request代表了请求 response代表响应 HttpServletResponse setStatus();----->发送状态码 setHeader();---->发送响应头 g ...

  9. ArcGIS Data Store 初体验

    1. 什么是ArcGIS Data Store? ArcGIS Data Store 是10.3新推出的一个组件,从官方对其定位来说,该组件是用来优化发布托管服务到portal for ArcGIS的 ...

  10. python基础知识体系

    一.编程风格.语法要求.变量格式.基本数据类型.运算.流程控制.用户交互 二.字符串.列表.元组.字典.迭代器和生成器 三.函数.内置函数.文件操作.异常处理.模块.常用模块.lambda.yield ...