【题解】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. Spring源码之循环依赖

    https://www.cnblogs.com/longy2012/articles/12834762.html https://www.bilibili.com/video/BV1iD4y1o7pM ...

  2. MongoDB笔记2018.2.6

    MongoDB笔记2018.2.6 1.先简单接触下linux,大部分教程是在linux环境下的操作,要不然看不懂教程 2.找教程或视频 教程推荐菜鸟教程 学习MongDB前需要懂一定的Mysql语法 ...

  3. Dubbo 初识SPI-Version2.7.5

    1简介 SPI 全称为 Service Provider Interface,是一种服务发现机制.SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类.这样可以在 ...

  4. HDU100题简要题解(2040~2049)

    HDU2040 亲和数 题目链接 Problem Description 古希腊数学家毕达哥拉斯在自然数研究中发现,220的所有真约数(即不是自身的约数)之和为: 1+2+4+5+10+11+20+2 ...

  5. B+树作为数据库索引有什么优势?I/O方面?

    首先要了解磁盘预读机制,大致就是说,从磁盘读取数据的速度比从内存读取数据的速度要慢很多,所以要尽量减少磁盘I/O的操作,尽量增加内存I/O操作,既然这样,我们可以从磁盘提前把需要的数据拿到内存,这样需 ...

  6. springboot实战开发全套教程,让开发像搭积木一样简单!Github星标已上10W+!

    前言 先说一下,这份教程在github上面星标已上10W,下面我会一一给大家举例出来全部内容,原链接后面我会发出来!首先我讲一下接下来我们会讲到的知识和技术,对比讲解了多种同类技术的使用手日区别,大家 ...

  7. 硕思logo设计师注册码去哪里找

    硕思logo设计师注册码去哪里找呢?当然是硕思logo设计师官网啦! 最近小编总是会被网友们咨询关于logo设计的问题,其中很多网友并不是专业的设计人员,特别是一些设计公司面对新手设计时,往往会不知所 ...

  8. 人人都能学会系列之ThreadLocal

    1.概览 本文我们来看下java.lang包中的ThreadLocal,它赋予我们给每个线程存储自己数据的能力. 2.ThreadLocal API ThreadLocal允许我们存储的数据只能被特定 ...

  9. 关于String类的一些知识点

    //原链接:https://blog.csdn.net/songylwq/article/details/7297004 String str=new String("abc"); ...

  10. Flink-1-状态化流处理概述

    第1章 状态化流处理概述 参考书籍 Stream Processing with Apache Flinkhttps://www.oreilly.com/library/view/stream-pro ...