用一个圆心在(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. 【转】android技术栈

    android技术栈-现有使用的进行一个汇总(初稿) 2017年04月24日 16:19:40 阅读数:2004 android技术栈 开发工具 Android studio 开发语言 Java 自动 ...

  2. re正则表达式公式讲解3

    1.分组匹配    用()把需要分组的类型括起来,如下 import re m = re.search("([a-z]+)([0-9]+)","alex123" ...

  3. [ POI 2017 ] Sabota?

    Description 题目链接 Solution 因为一个节点染黑了子树就都被染黑了,所以最后染黑的点集必然是一棵子树. 可以得出的结论是,如果被染黑的节点在节点 \(a\) 的子树中,而 \(a\ ...

  4. 职业生涯手记——电视剧剧情O.O

    很多电视剧.偶像剧.电影里出现过一些场景,从来没想过狗血剧情是来源于现实.. 直到上周一开始,我慢慢相信了.. 事情是这样的. 我们小组有个组员H,从上周一开始他每天都去公司的座机电话接1~2个电话, ...

  5. docker 搭建 Java Web 运行环境

    安装环境:jdk,tomcat,mysql,nginx

  6. vs code 插件list

    vs code 插件list

  7. es6 fs 输出文件 iviewDemo

    // fs.open('./env.js', 'w', function(err, fd) { // // const buf = 'export default "development& ...

  8. django URL,views,html请求顺序

    进来的请求转入/hello/.   Django通过在ROOT_URLCONF配置来决定根URLconf.     Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目 ...

  9. Linux-03 Linux下的tar命令

    功能说明 用来建立,还原备份文件的工具程序,它可以加入,解开备份文件内的文件 参数 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五 ...

  10. 谈谈你对java的理解

    这个题目是考察多个方面 但是要回答出关键点: 1.平台无关性 2.GC 3.语言特性.泛型.反射.lamda 4.面向对象 5.类库 6.异常处理