题面

传送门

前置芝士

最小圆覆盖

题解

我们按照\(x\)坐标排序,然后二分中间点,把点分成左右两边,对两边都做一个最小圆覆盖,那么半径大一点的那个就是答案了。然后对半径大的那一边继续二分就行了

然而这里显然会有一个问题……就是如果最优解中把点分成两个点集的那条直线是斜的该怎么办……

那么我们就把整个坐标系转一下好了……枚举一下偏角,然后把所有点逆时针转过这个角度……实测大概每次转\({2\pi \over 100}\),转\(100\)次差不多就可以了

还有一个我很好奇的问题,如果有三点共线的情况,那么最小圆覆盖求两条中垂线交点的时候可能会出现中垂线平行的情况显然是会\(gg\)的,所以解决办法要么是特判平行要么是加上微小扰动来避免三点共线,然而我看了看别人的似乎都没管这一点也能\(A\)……

哪位鸽鸽能告诉我这是为什么么qwq

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
double readdb()
{
R double x=0,y=0.1,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(x=ch-'0';(ch=getc())>='0'&&ch<='9';x=x*10+ch-'0');
for(ch=='.'&&(ch=getc());ch>='0'&&ch<='9';x+=(ch-'0')*y,y*=0.1,ch=getc());
return x*f;
}
const int N=1005;const double an=1.0/100*acos(-1.0),eps=1e-9;
const double si=sin(an),co=cos(an);
inline int sgn(R double x){return x<-eps?-1:x>eps;}
inline double reps(){return (1.0*rand()/RAND_MAX-0.5)*eps;}
struct node{
double x,y;
inline node(){}
inline node(R double xx,R double yy):x(xx),y(yy){}
inline node operator +(const node &b)const{return node(x+b.x,y+b.y);}
inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
inline double operator *(const node &b)const{return x*b.y-y*b.x;}
inline node operator *(const double &b)const{return node(x*b,y*b);}
inline double operator ^(const node &b)const{return x*b.x+y*b.y;}
inline double len2(){return x*x+y*y;}
inline node rot(){return node(x*co-y*si,x*si+y*co);}
inline node rot90(){return node(-y,x);}
inline void shake(){x+=reps(),y+=reps();}
}p[N],st[N],o;
inline bool cmp(const node &a,const node &b){return a.x<b.x;}
struct Line{
node p,v;
inline Line(){}
inline Line(R node pp,R node vv):p(pp),v(vv){}
friend node cross(const Line &a,const Line &b){return a.p+a.v*(b.v*(b.p-a.p)/(b.v*a.v));}
};
node circle(R node a,R node b,R node c){
return cross(Line((a+b)*0.5,(b-a).rot90()),Line((a+c)*0.5,(c-a).rot90()));
}
double query(int l1,int l2){
if(l1>l2)return 0;
int top=0;double r=0;o=node(0,0);
fp(i,l1,l2)st[++top]=p[i];
random_shuffle(st+1,st+1+top);
fp(i,1,top)if(sgn((st[i]-o).len2()-r)>0){
o=st[i],r=0;
fp(j,1,i-1)if(sgn((st[j]-o).len2()-r)>0){
o=(st[i]+st[j])*0.5,r=(st[i]-o).len2();
fp(k,1,j-1)if(sgn((st[k]-o).len2()-r)>0)
o=circle(st[i],st[j],st[k]),r=(st[i]-o).len2();
}
}
return r;
}
int n;double res;
int main(){
srand(20030719);
// freopen("testdata.in","r",stdin);
while(n=read()){
fp(i,1,n)p[i].x=readdb(),p[i].y=readdb(),p[i].shake();
res=1e18;
fp(d,1,160){
fp(i,1,n)p[i]=p[i].rot();
sort(p+1,p+1+n,cmp);
int l=1,r=n;
while(l<=r){
int mid=(l+r)>>1;
double r1=query(1,mid),r2=query(mid+1,n);
double ans=r1<r2?r2:r1;
if(r1+r2-ans>res)break;
cmin(res,ans);
r1<r2?l=mid+1:r=mid-1;
}
}
printf("%.2lf\n",sqrt(res));
}
return 0;
}

洛谷P4586 [FJOI2015]最小覆盖双圆问题(最小圆覆盖)的更多相关文章

  1. 洛谷 P4585 [FJOI2015]火星商店问题 解题报告

    P4585 [FJOI2015]火星商店问题 题目描述 火星上的一条商业街里按照商店的编号\(1,2,\dots,n\) ,依次排列着\(n\)个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非 ...

  2. 洛谷 P4585 [FJOI2015]火星商店问题

    (勿看,仅作笔记) bzoj权限题... https://www.luogu.org/problemnew/show/P4585 对于特殊商品,直接可持久化trie处理一下即可 剩下的,想了一段时间c ...

  3. 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树

    正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...

  4. [洛谷P4585] [FJOI2015] 火星商店问题

    Description 火星上的一条商业街里按照商店的编号 \(1\),\(2\) ,-,\(n\) ,依次排列着 \(n\) 个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非负整数 \(va ...

  5. 【洛谷】P4585 [FJOI2015]火星商店问题

    题解 题目太丧,OJ太没有良心,我永远喜欢LOJ! (TLE报成RE,垃圾洛谷,我永远喜欢LOJ) 好的,平复一下我debug了一上午崩溃的心态= =,写一写这道题的题解 把所有限制去掉,给出一个值, ...

  6. (bzoj1337 || 洛谷P1742 最小圆覆盖 )|| (bzoj2823 || 洛谷P2533 [AHOI2012]信号塔)

    bzoj1337 洛谷P1742 用随机增量法.讲解:https://blog.csdn.net/jokerwyt/article/details/79221345 设点集A的最小覆盖圆为g(A) 可 ...

  7. 洛谷 P2279 [HNOI2003]消防局的设立 (树形dp or 贪心)

    一看到这道题就知道是树形dp 之前做过类似的题,只不过保护的范围是1 所以简单很多. 这道题保护的范围是2,就复杂了很多. 我就开始列状态,然后发现竟然有5种 然后我就开始列方程. 但是我考虑的时候是 ...

  8. 洛谷 P1514 【引水入城】

    题库 :洛谷 题号 :1514 题目 :引水入城 link :https://www.luogu.org/problemnew/show/P1514 思路 :搜索从第一排开始能覆盖最后一排的区间L ~ ...

  9. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

随机推荐

  1. (转 留存)Windows环境下的NodeJS+NPM+GIT+Bower安装配置步骤

    Windows环境下的NodeJS+NPM+GIT+Bower安装配置步骤 标签: NodeJSnpmbower 2015-07-17 16:38 3016人阅读 评论(0) 收藏 举报  分类: G ...

  2. 发布spring jar包, 报错

    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Una ...

  3. 初步认识cookie

    cookie是由服务器创建,客户端读取及保存它的 同类请求指的是资源路径相同 Cookie的默认路径绑定是所请求的资源路径绑定的 ,指定路径时必须要有项目名称(说明是哪个项目) 使用cookie时还要 ...

  4. fixed语句

    [fixed语句] fixed 语句禁止垃圾回收器重定位可移动的变量.fixed 语句只能出现在不安全的上下文中.Fixed 还可用于创建固定大小的缓冲区. fixed 语句设置指向托管变量的指针,并 ...

  5. java用while循环设计轮询线程的性能问题

    java用while循环设计轮询线程的性能问题 轮询线程在开发过程中的应用是比较广泛的,在这我模拟一个场景,有一个队列和轮询线程,主线程往队列中入队消息,轮询线程循环从队列中读取消息并打印消息内容.有 ...

  6. VUE递归树形目录(vue递归组件)的使用

    1.html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ...

  7. 在 Ruby 中执行 Shell 命令的 6 种方法

    我们时常会与操作系统交互或在 Ruby 中执行 Shell 命令.Ruby为我们提供了完成该任务的诸多方法. Exec Kernel#exec 通过执行给定的命令来替换当前进程,例如: $ irb & ...

  8. win8上部署.net4.0程序到iis

    在win8.1上默认的iis版本为8.5版,不做任何配置回报3个错误, 一下是错误提示内容及解决方案 1>HTTP 错误 404.3 – Not Found由于扩展配置问题而无法提供您请求的页面 ...

  9. SQLSERVER CROSS APPLY 与 OUTER APPLY 的应用

    日常开发中遇到多表查询时,首先会想到 INNER JOIN 或 LEFT OUTER JOIN 等等,但是这两种查询有时候不能满足需求.比如,左表一条关联右表多条记录时,我需要控制右表的某一条或多条记 ...

  10. [Training Video - 2] [Groovy Introduction]

    Building test suites, Test cases and Test steps in SOAP UI Levels : test step level test case level ...