用一个圆心在(x,y)的圆环覆盖一个n边形,顺或逆时针给出n边形所有顶点,求圆环最小面积。

卡了好久,各种傻逼错误。。

题目就是让我们固定一大一小两个边界圆,我们来看看这两个圆满足什么条件。

首先外面的那个圆肯定是经过n边形的某个顶点,所以外圆半径就是最大的点距。

其次内圆呢,可能经过一个点,也可能与某条边相切,但注意,这里的线是线段不是直线!

所以可能会出现最后的内圆和某条“直线”相交而与其对应的线段没有交点。例如:

上图中内圆与四条“直线”都相交,但与“线段”只有一个交点。

为了判断内圆,我用了最粗暴的方法--二分,计算与当前半径的圆相交的“直线“的两个交点是否在“线段”上,用横坐标或纵坐标判断。

Trick:

如果是用y=kx+b就会wa,因为平面上不是所有的直线都能这么表示,要用一般式Ax+By+C=0。

计算圆与直线相交情况时记得分B是否为0的情况。所有计算过程中记得判断除0情况。

精度。二分时在精度那里要注意R-eps或者L+eps,不然可能tle。

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
//#include<iostream>
using namespace std; int n;
#define maxn 100011
struct Point
{
double x,y;
}a[maxn],P;
struct Line
{
double a,b,c,dis;
}l[maxn];
const double eps=1e-,pi=3.1415926535897932384626434;
void do_line(int id,double x1,double y1,double x2,double y2)
{
if (x1==x2)
{
l[id].a=;
l[id].b=;
l[id].c=-x1;
}
else if (y1==y2)
{
l[id].a=;
l[id].b=;
l[id].c=-y1;
}
else if (x2*y1==x1*y2)
{
l[id].c=;
l[id].a=;
if (y1) l[id].b=-x1/y1*l[id].a;
else l[id].b=-x2/y2*l[id].a;
}
else
{
l[id].c=;
l[id].a=l[id].c*(y2-y1)/(x2*y1-x1*y2);
l[id].b=l[id].c*(x2-x1)/(y2*x1-y1*x2);
}
l[id].dis=abs(l[id].a*P.x+l[id].b*P.y+l[id].c)/sqrt(l[id].a*l[id].a+l[id].b*l[id].b);
}
double ppdissqr(double x1,double y1,double x2,double y2)
{
return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
}
bool judge(double x)
{
for (int i=;i<=n;i++)
if (l[i].dis-x<=-eps)
{
double A=l[i].a,B=l[i].b,C=l[i].c;
if (B)
{
double delta=((A/B)*(A/B)+)*x*x-((A*P.x+C)/B+P.y)*((A*P.x+C)/B+P.y),
x1=(-*(A/B*(C/B+P.y)-P.x)+sqrt(delta))/(*(+(A/B)*(A/B))),
x2=(-*(A/B*(C/B+P.y)-P.x)-sqrt(delta))/(*(+(A/B)*(A/B)));
double p=a[i].x,q=a[i+].x;
if (i==n) q=a[].x;
if (p>q) swap(p,q);
if ((x1>=p && x1<=q)
|| (x2>=p && x2<=q))
return ;
}
else
{
double y1=P.y+sqrt(x*x-(-C/A-P.x)*(-C/A-P.x)),
y2=P.y-sqrt(x*x-(-C/A-P.x)*(-C/A-P.x));
double p=a[i].y,q=a[i+].y;
if (i==n) q=a[].y;
if (p>q) swap(p,q);
if ((y1>=p && y1<=q)
|| (y2>=p && y2<=q))
return ;
}
}
return ;
}
int main()
{
scanf("%d%lf%lf",&n,&P.x,&P.y);
for (int i=;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
for (int i=;i<n;i++)
do_line(i,a[i].x,a[i].y,a[i+].x,a[i+].y);
do_line(n,a[n].x,a[n].y,a[].x,a[].y);
double f1=0.0,r2,L=0.0,R;
for (int i=;i<=n;i++)
f1=max(f1,ppdissqr(a[i].x,a[i].y,P.x,P.y));
R=sqrt(f1);
for (int i=;i<=n;i++)
R=min(R,sqrt(ppdissqr(a[i].x,a[i].y,P.x,P.y)));
while (R-L>eps)
{
double mid=(L+R+eps)/;
if (judge(mid)) L=mid;
else R=mid-eps;
}
r2=(L+R)/;
printf("%.10lf\n",pi*(f1-r2*r2));
return ;
}

CF613A:Peter and Snow Blower的更多相关文章

  1. Codeforces Round #339 (Div. 1) A. Peter and Snow Blower 计算几何

    A. Peter and Snow Blower 题目连接: http://www.codeforces.com/contest/613/problem/A Description Peter got ...

  2. codeforce #339(div2)C Peter and Snow Blower

    Peter and Snow Blower 题意:有n(3 <= n <= 100 000)个点的一个多边形,这个多边形绕一个顶点转动,问扫过的面积为多少? 思路:开始就认为是一个凸包的问 ...

  3. A. Peter and Snow Blower 解析(思維、幾何)

    Codeforce 613 A. Peter and Snow Blower 解析(思維.幾何) 今天我們來看看CF613A 題目連結 題目 給你一個點\(P\)和\(n\)個點形成的多邊形(照順或逆 ...

  4. [CodeForces - 614C] C - Peter and Snow Blower

    C - Peter and Snow Blower Peter got a new snow blower as a New Year present. Of course, Peter decide ...

  5. Codeforces Round #339 Div.2 C - Peter and Snow Blower

    Peter got a new snow blower as a New Year present. Of course, Peter decided to try it immediately. A ...

  6. 【14.36%】【codeforces 614C】Peter and Snow Blower

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. 【CodeForces 613A】Peter and Snow Blower

    题 题意 给出原点(不是(0,0)那个原点)的坐标和一个多边形的顶点坐标,求多边形绕原点转一圈扫过的面积(每个顶点到原点距离保持不变). 分析 多边形到原点的最小距离和最大距离构成的两个圆之间的圆环就 ...

  8. codeforces 613A. Peter and Snow Blower

    题目链接 给一个多边形, 一个多边形外的定点, 求这个点距离多边形的最短距离和最长距离. 最长距离肯定是和某个顶点的连线, 而最短距离是和点的连线或是和某条边的连线. 对于一条边上的两个点a, b, ...

  9. CodeForces 614C Peter and Snow Blower

    简单计算几何,只要算出圆心到多边形上的最短距离和最长距离即可 #include<cstdio> #include<cstring> #include<cmath> ...

随机推荐

  1. js递归和数组去重(简单便捷的用法)

    1.递归例子<script type="text/javascript"> function test(num) { if(num < 0) { return; ...

  2. 在windows上安装Jenkins---tomcat流

    在windows上安装Jenkins有两种方式: (1)jar流 在命令行中运行:java -jar jenkins.war 浏览器访问 localhost:8080,创建初始管理员帐号即可. (2) ...

  3. Django创建第一个应用

    一.创建第一个应用,并在settings.py中添加. python manage.py startapp article 二.创建第一个模型 class Article(models.Model): ...

  4. mysql踩坑记录之limit和sum函数混合使用问题

    问题复盘本次复盘会用一个很简单的订单表作为示例. 数据准备订单表建表语句如下(这里偷懒了,使用了自增ID,实际开发中不建议使用自增ID作为订单ID) CREATE TABLE `order` ( `i ...

  5. 最短路 || POJ 1797 Heavy Transportation

    Background Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand bus ...

  6. CentOS7.6 修改密码

    一.重启系统,在开机过程中,按下键盘上的e,进入编辑模式   三.将光标一直移动到 LANG=en_US.UTF-8 后面,空格,再追加init=/bin/sh.这里特别注意,需要写在UTF-8后,保 ...

  7. ios7与ios6UI风格区别

    http://apple.xdnice.com/content/applenews/2013/0614/142195.html         (ios7 ui风格) http://blog.csdn ...

  8. WEB 前端模块化,读文笔记

    文章链接 WEB 前端模块化都有什么? 知识点 根据平台划分 浏览器 AMD.CMD 存在网络瓶颈,使用异步加载 非浏览器 CommonJS 直接操作 IO,同步加载 浏览器 AMD 依赖前置 req ...

  9. Ubuntu下压缩与解压各种文件的命令

    1.压缩与解压xz文件 (1)压缩 xz -z  filename (2)解压 xz -d  filename.xz 2.压缩与解压tar文件 (1)压缩 tar -cvf  filename(压缩到 ...

  10. Gym-101615C-Fear Factoring(数论)

    分析 题意是求 L - R之间的数的因数和 我们知道如果对于一个数 i ( i < k = sqrt(R)),那么一定有一个数 R/i 也是R的因数 遍历 i = 2 - k,然后对于每一个 i ...