CF613A:Peter and Snow Blower
用一个圆心在(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的更多相关文章
- 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 ...
- codeforce #339(div2)C Peter and Snow Blower
Peter and Snow Blower 题意:有n(3 <= n <= 100 000)个点的一个多边形,这个多边形绕一个顶点转动,问扫过的面积为多少? 思路:开始就认为是一个凸包的问 ...
- A. Peter and Snow Blower 解析(思維、幾何)
Codeforce 613 A. Peter and Snow Blower 解析(思維.幾何) 今天我們來看看CF613A 題目連結 題目 給你一個點\(P\)和\(n\)個點形成的多邊形(照順或逆 ...
- [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 ...
- 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 ...
- 【14.36%】【codeforces 614C】Peter and Snow Blower
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【CodeForces 613A】Peter and Snow Blower
题 题意 给出原点(不是(0,0)那个原点)的坐标和一个多边形的顶点坐标,求多边形绕原点转一圈扫过的面积(每个顶点到原点距离保持不变). 分析 多边形到原点的最小距离和最大距离构成的两个圆之间的圆环就 ...
- codeforces 613A. Peter and Snow Blower
题目链接 给一个多边形, 一个多边形外的定点, 求这个点距离多边形的最短距离和最长距离. 最长距离肯定是和某个顶点的连线, 而最短距离是和点的连线或是和某条边的连线. 对于一条边上的两个点a, b, ...
- CodeForces 614C Peter and Snow Blower
简单计算几何,只要算出圆心到多边形上的最短距离和最长距离即可 #include<cstdio> #include<cstring> #include<cmath> ...
随机推荐
- 【转】java节省内存的几条建议
下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单 ...
- 公有云大脑——核心IDC简影
出差刚到家,公司最近接了一个矿场转建公有云平台的项目. 前期200台服务器作为公有云基础. 我主要负责总体网络规划.计费数据库集群设计.ceph集群自动部署.容器化设计.硬件及系统调试优化等等! 由于 ...
- 26款优秀的Android逆向工程工具
26款优秀的Android逆向工程工具
- Android Learning Note -- AsyncTask浅尝
AsyncTask 实现原理 AsyncTask是Android提供的轻量级异步类,可以直接继承AsyncTask在类中实现异步操作,并提供接口反馈当前的异步执行程度(通过接口实现UI进度更新),最后 ...
- sc服务查询
sc query lanmanse2rver |find /i "state" |find /i "running" || ( echo 该服务没有运行时,要执 ...
- TFS2010单独安装配置tfs build server
记录一下确实很磨人. 同样硬件和软件环境的两台服务器,其中一台服务器很久之前就配置好了tfs2010 build ,然后最近想再配置一台tfs build server,但是按照以前的配置流程始终提示 ...
- python笔记_magic变量和函数
前言 先扯一点背景知识 PEP8(Python Enhancement Proposal)是一份python的编码规范,链接:http://www.python.org/dev/peps/pep-00 ...
- mount nfs 各版本之间的转换
[root@one1-fst-hx ~]# mount.nfs 182.168.2.49:/mnt/sdb/nfs /mnt/nfs2/ nomand,-o vers=3[root@one1-fst- ...
- 清空表单方法 清空变量 iview modal
方法一 通过json序列号和反序列号 清空一次数据 数据需要copy出来一份 orgFormClearAllInput () { this.$refs.n1.formValidate = JSON.p ...
- Object.assign(o1, o2, o3) 对象 复制 合拼
Object 对象方法学习之(1)—— 使用 Object.assign 复制对象.合并对象 合并对象 var o1 = {a: 1}; var o2 = {b: 2}; var o3 = {c: 3 ...