【题解】The Last Hole! [CF274C]
【题解】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]的更多相关文章
- 题解——洛谷P1550 [USACO08OCT]打井Watering Hole(最小生成树,建图)
题面 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to his N (1 <= N <= 300) pas ...
- 题解 P1550 【[USACO08OCT]打井Watering Hole】
题面(翻译有点问题,最后一句话) 农民John 决定将水引入到他的n(1<=n<=300)个牧场.他准备通过挖若 干井,并在各块田中修筑水道来连通各块田地以供水.在第i 号田中挖一口井需要 ...
- FJNUOJ Yehan’s hole(容斥求路径数 + 逆元)题解
Description Yehan is a angry grumpy rabbit, who likes jumping into the hole. This day,Yehan jumps ag ...
- PAT甲题题解-1069. The Black Hole of Numbers (20)-模拟
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789244.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- 洛谷 题解 P1550 【[USACO08OCT]打井Watering Hole】
本题看似很难,实际上思路非常简单--如果你想通了. 首先有一个问题:图中有几个点?大部分的人会回答\(n\)个点.错了,有\(n+1\)个. 多出来的那个点在哪?关键在于你要理解每一个决策的意义.实际 ...
- Kruskal || BZOJ 1601: [Usaco2008 Oct]灌水 || Luogu P1550 [USACO08OCT]打井Watering Hole
题面:P1550 [USACO08OCT]打井Watering Hole 题解:无 代码: #include<cstdio> #include<cstring> #includ ...
- PAT甲级题解(慢慢刷中)
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- Luogu P1550 打井Watering Hole
P1550 [USACO08OCT]打井Watering Hole 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to ...
- AtCoder Grand Contest 021完整题解
提示:如果公式挂了请多刷新几次,MathJex的公式渲染速度并不是那么理想. 总的来说,还是自己太弱了啊.只做了T1,还WA了两发.今天还有一场CodeForces,晚上0点qwq... 题解还是要好 ...
随机推荐
- HiveMQ TDengine extension 使用指南
我们简单介绍一下 HiveMQ extension for TDengine 的部署和使用方法. TDengine 和 HiveMQ 部署方法 TDengine 安装最新 TDengine serve ...
- kafka常见面试题
1.Kafka 中的 ISR(InSyncRepli).OSR(OutSyncRepli).AR(AllRepli)代表什么? 1.AR = ISR+OSR ISR: kafka 使用多副本来保证消息 ...
- dp背包 面试题 08.11. 硬币
https://leetcode-cn.com/problems/coin-lcci/ 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算n分有几种表示法.(结果可能会很大,你需 ...
- Tomcat Web服务器与常用Web服务器
一.常用Web服务器 Tomcat 由Apache组织提供的一种Web服务器,提供对jsp和servlet的支持.它是一种轻量级的javaWeb容器服务器.也是当前应用最广的JavaWeb服务器( ...
- 2018.1.15复习_ css+js
[1]几个常见的css标签:--------------------------------------------------background-color; 设置背景颜色background-p ...
- 结合实战和源码来聊聊Java中的SPI机制?
写在前面 SPI机制能够非常方便的为某个接口动态指定其实现类,在某种程度上,这也是某些框架具有高度可扩展性的基础.今天,我们就从源码级别深入探讨下Java中的SPI机制. 注:文章已收录到:https ...
- Nginx下关于缓存控制字段cache-control的配置说明
HTTP协议的Cache -Control指定请求和响应遵循的缓存机制.在请求消息或响应消息中设置 Cache-Control并不会影响另一个消息处理过程中的缓存处理过程.请求时的缓存指令包括: no ...
- Docker学习第四天(Dockerfile)
dockerfile Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本 Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个 ...
- CTF练习(1)这是一张单纯的图片?
1.练习平台http://123.206.31.85/challenges 2.图片下载后放进WInhex 最后安利一个 CTF资源库|CTF工具包|CTF工具集合 网站,里面工具很全,很方便 ...
- sqlilab less11-less18
less-11 uname和passwd直接带入查询,万能密码 sqlmap自动搜索表单,或者抓包后用-r参数 less-12 post数据用小括号进行包裹,构造万能密码") or 1=1 ...