【题解】The Last Hole! [CF274C]

传送门:\(\text{The Last Hole!}\) \(\text{[CF274C]}\)

【题目描述】

给出平面上 \(n\) 个圆的圆心坐标,最开始它们的半径都是 \(0\),然后所有圆同时开始扩大,在时刻 \(t\) 时所有圆的半径均为 \(t\) 。

假设这些黑色的圆被放在一个无穷大的白色平面上,每个时刻都存在一些黑色、白色连通块。随着圆的逐渐增大,越来越多的圆会相交。

定义一个白色的封闭区域为一个“洞”,求最后一个“洞”消失的时刻。如果没有“洞”则输出 \(-1\)。

答案精度差不能超过 \(10^{-4}\) 。

【分析】

【计算几何全家桶】

画个图感受一下,发现所有的♂洞♂都可以简化为两种情况:由 呈锐角三角形的三个圆 或者 呈矩形的四个圆 所生成(指圆心呈 XX 形状)。

可以直接 \(O(n^3)\) 枚举包围圈,可知“洞”消失的部位一定是 外心/对角线交点。对于三角形取外接圆半径,对于矩形则取对角线长度一半,最后找最大值即为答案。

给出三角形顶点坐标不会求外接圆的,这里有个板子(输出有点鬼畜):\(\text{Circle Through Three Points [UVA190]}\)

但这样做的话在 \(\text{test 6}\) 就会 \(\text{WA}\) :

4
0 0
4 8
8 0
4 3

按照上述做法求出来答案为 \(5\),而实际上三角形外心与另一个圆心 \((4,3)\) 重合了,也就是说根本就不会出现“洞”。

所以正确做法应该是把所以可能的“洞”的消失点储存下来,并计算它在选出来的包围圈中消失所需时间 \(ti\) 。最后扫一遍所有圆,如果所有圆都没有在 \(ti\) 之前覆盖掉这个点,那么 \(ti\) 就是合法的。

时间复杂度为:\(O(n^3+kn)\),其中 \(k\) 为储存下来的可能消失点个数,由于不合法的较多,远达不到上界 \(n^3\),可以轻松水过。

【Code】

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define LD double
#define LL long long
#define Re register int
#define Vector Point
#define mp make_pair
#define S(a) ((a)*(a))
using namespace std;
const int N=103;
const LD eps=1e-10;
inline int dcmp(LD a){return a<-eps?-1:(a>eps?1:0);}//处理精度
inline LD Abs(LD a){return a*dcmp(a);}//取绝对值
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
struct Point{LD x,y;Point(LD X=0,LD Y=0){x=X,y=Y;}};
inline LD Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//【点积】
inline LD Cro(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//【叉积】
inline LD Len(Vector a){return sqrt(Dot(a,a));}//【模长】
inline Vector operator+(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);}
inline Vector operator-(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
inline Vector operator*(Vector a,LD b){return Vector(a.x*b,a.y*b);}
inline bool operator==(Point a,Point b){return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y);}
struct Circle{Point O;LD r;Circle(Point P,LD R=0){O=P,r=R;}};
inline Circle getcircle(Point A,Point B,Point C){//三点确定一圆
LD x1=A.x,y1=A.y,x2=B.x,y2=B.y,x3=C.x,y3=C.y;
LD D=((S(x2)+S(y2)-S(x3)-S(y3))*(y1-y2)-(S(x1)+S(y1)-S(x2)-S(y2))*(y2-y3))/((x1-x2)*(y2-y3)-(x2-x3)*(y1-y2));
LD E=(dcmp(y2-y1)!=0)?(S(x1)+S(y1)-S(x2)-S(y2)+D*(x1-x2))/(y2-y1):(S(x2)+S(y2)-S(x3)-S(y3)+D*(x2-x3))/(y3-y2);
LD F=-(S(x1)+S(y1)+D*x1+E*y1);
return Circle(Point(-D/2.0,-E/2.0),sqrt((S(D)+S(E)-4.0*F)/4.0));
}
inline int pan_PL_(Point p,Point a,Point b){//【判断点P是否在直线AB上】
return !dcmp(Cro(p-a,b-a));//PA,AB共线
}
int n,cnt,X[N],Y[N];Point P[N],Q[N*N*N];LD ti[N*N*N];LD ans=-1;map<pair<int,int>,int>vis;
inline void sakura1(Point A,Point B,Point C){//处理三角形
if(dcmp(Dot(A-B,C-B))<=0||dcmp(Dot(A-C,B-C))<=0||dcmp(Dot(B-A,C-A))<=0)return;//钝角三角形、直角三角形都不要
// printf("(%.lf,%.lf) (%.lf,%.lf) (%.lf,%.lf)\n",A.x,A.y,B.x,B.y,C.x,C.y);
Circle Cir=getcircle(A,B,C);Q[++cnt]=Cir.O,ti[cnt]=Cir.r;
}
inline void sakura2_(Re i,Re j,Re k){//假设i为左下角,j为左上角,k为右下角
if(X[i]==X[j]&&Y[i]<Y[j]&&Y[i]==Y[k]&&X[i]<X[k]){
// printf("(%d,%d) (%d,%d) (%d,%d)\n",X[i],Y[i],X[j],Y[j],X[k],Y[k]);
if(vis[mp(X[k],Y[j])])Q[++cnt]=Point((X[i]+X[k])/2.0,(Y[i]+Y[j])/2.0),ti[cnt]=Len(P[j]-P[k])/2.0;
}
}
inline void sakura2(Re i,Re j,Re k){//处理矩形
sakura2_(i,j,k),sakura2_(j,i,k),sakura2_(k,i,j);//枚举6种i,j,k可能的组合,
sakura2_(i,k,j),sakura2_(j,k,i),sakura2_(k,j,i);//最后需要的只有1种
}
int main(){
// freopen("123.txt","r",stdin);
in(n);
for(Re i=1;i<=n;++i)in(X[i]),in(Y[i]),vis[mp(X[i],Y[i])]=1,P[i]=Point(X[i],Y[i]);
for(Re i=1;i<=n;++i)//不重复的枚举i,j,k
for(Re j=i+1;j<=n;++j)
for(Re k=j+1;k<=n;++k)
if(!pan_PL_(P[i],P[j],P[k]))//如果三点不共线
sakura1(P[i],P[j],P[k]),sakura2(i,j,k);
for(Re i=1;i<=cnt;++i){
Re flag=1;
for(Re j=1;j<=n&&flag;++j)flag&=(dcmp(Len(Q[i]-P[j])-ti[i])>=0);//如果在ti[i]之前就被某个点覆盖了
if(flag)ans=max(ans,ti[i]);
}
printf("%lf\n",ans);
}

【题解】The Last Hole! [CF274C]的更多相关文章

  1. 题解——洛谷P1550 [USACO08OCT]打井Watering Hole(最小生成树,建图)

    题面 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pas ...

  2. 题解 P1550 【[USACO08OCT]打井Watering Hole】

    题面(翻译有点问题,最后一句话) 农民John 决定将水引入到他的n(1<=n<=300)个牧场.他准备通过挖若 干井,并在各块田中修筑水道来连通各块田地以供水.在第i 号田中挖一口井需要 ...

  3. FJNUOJ Yehan’s hole(容斥求路径数 + 逆元)题解

    Description Yehan is a angry grumpy rabbit, who likes jumping into the hole. This day,Yehan jumps ag ...

  4. PAT甲题题解-1069. The Black Hole of Numbers (20)-模拟

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789244.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  5. 洛谷 题解 P1550 【[USACO08OCT]打井Watering Hole】

    本题看似很难,实际上思路非常简单--如果你想通了. 首先有一个问题:图中有几个点?大部分的人会回答\(n\)个点.错了,有\(n+1\)个. 多出来的那个点在哪?关键在于你要理解每一个决策的意义.实际 ...

  6. Kruskal || BZOJ 1601: [Usaco2008 Oct]灌水 || Luogu P1550 [USACO08OCT]打井Watering Hole

    题面:P1550 [USACO08OCT]打井Watering Hole 题解:无 代码: #include<cstdio> #include<cstring> #includ ...

  7. PAT甲级题解(慢慢刷中)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  8. Luogu P1550 打井Watering Hole

    P1550 [USACO08OCT]打井Watering Hole 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to ...

  9. AtCoder Grand Contest 021完整题解

    提示:如果公式挂了请多刷新几次,MathJex的公式渲染速度并不是那么理想. 总的来说,还是自己太弱了啊.只做了T1,还WA了两发.今天还有一场CodeForces,晚上0点qwq... 题解还是要好 ...

随机推荐

  1. Redis下载

    Windows版下载地址 https://github.com/tporadowski/redis/releases Linux版下载地址 https://redis.io/download

  2. linux c语言编写一个shell壳

    目的:我们要用c语言编写一个shell可以运行在linux机器上的. 介绍:shell所在的层次 我们要做的是操作系统,用于用户与操作系统进行交互的myhsell 思路:用户输入  一行字符串,我们先 ...

  3. 性能工具-io工具

    I/O:某网上问题通过top  iotop pidstat vmstat 工具定位出io高原因,内存不够.

  4. rgw的rgw_thread_pool_size配置调整

    前言 在比对rgw的不同前端的区别的时候,官方说civetweb是通过线程池来控制连接的,beast是后面加入了流控相关的,这块一直也没有调整过相关的参数,然后通过ab压测了一下,还是有很明显的区别的 ...

  5. SSL加密原理

    对称加密算法 对称加密算法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密. 非对称加密算法 非对称加密算法(RSA)是内容加密的一类算法,它有两个秘钥:公钥与私钥 ...

  6. Codeforces1009F Dominant Indices

    dsu on tree 题目链接 点我跳转 题目大意 给定一棵以 \(1\) 为根,\(n\) 个节点的树.设\(d(u,x)\) 为 \(u\) 子树中到 \(u\) 距离为 \(x\) 的节点数. ...

  7. 云原生应用Go语言:你还在考虑的时候,别人已经应用实践

    摘要:在近日于上海召开的第六届Gopher China大会上,华为云微服务首席架构师田晓亮分享了<华为云的Go语言云原生实战经验>,讲述如何构建韧性.高可靠.安全的云原生应用系统,并孵化云 ...

  8. 在线思维导图Ayoa有哪些比较好用的功能

    思维导图是非常实用的一种工具,现在网上有很多制作思维导图的软件,小编也用过很多款软件,今天就和大家分享一款思维导图逆天软件:Ayoa. 用了这款软件后,小编对思维导图的理解刷新了高度,下面就为大家推荐 ...

  9. centos8 yum 升级nginx

    原文地址:https://blog.csdn.net/lpwmm/article/details/105627476 CentOS8的Yum仓库中内置的nginx版本是1.14.1,最近漏扫提示需要升 ...

  10. 免费AWS云服务器一键搭建Trojan详细教程

    前言 想要撸AWS服务器的可以看我上一篇博客,这里就不介绍了,以下步骤有问题的朋友可以私信或者评论区留言. 配置AWS云服务器 选择语言,博主写了博客后才看到,前面都是使用谷歌翻译. 选择地区 创建虚 ...