洛谷P4586 [FJOI2015]最小覆盖双圆问题(最小圆覆盖)
题面
前置芝士
题解
我们按照\(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]最小覆盖双圆问题(最小圆覆盖)的更多相关文章
- 洛谷 P4585 [FJOI2015]火星商店问题 解题报告
P4585 [FJOI2015]火星商店问题 题目描述 火星上的一条商业街里按照商店的编号\(1,2,\dots,n\) ,依次排列着\(n\)个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非 ...
- 洛谷 P4585 [FJOI2015]火星商店问题
(勿看,仅作笔记) bzoj权限题... https://www.luogu.org/problemnew/show/P4585 对于特殊商品,直接可持久化trie处理一下即可 剩下的,想了一段时间c ...
- 洛谷$P4585\ [FJOI2015]$火星商店问题 线段树+$trie$树
正解:线段树+$trie$树 解题报告: 传送门$QwQ$ $umm$题目有点儿长我先写下题目大意趴$QwQ$,就说有$n$个初始均为空的集合和$m$次操作,每次操作为向某个集合内加入一个数$x$,或 ...
- [洛谷P4585] [FJOI2015] 火星商店问题
Description 火星上的一条商业街里按照商店的编号 \(1\),\(2\) ,-,\(n\) ,依次排列着 \(n\) 个商店.商店里出售的琳琅满目的商品中,每种商品都用一个非负整数 \(va ...
- 【洛谷】P4585 [FJOI2015]火星商店问题
题解 题目太丧,OJ太没有良心,我永远喜欢LOJ! (TLE报成RE,垃圾洛谷,我永远喜欢LOJ) 好的,平复一下我debug了一上午崩溃的心态= =,写一写这道题的题解 把所有限制去掉,给出一个值, ...
- (bzoj1337 || 洛谷P1742 最小圆覆盖 )|| (bzoj2823 || 洛谷P2533 [AHOI2012]信号塔)
bzoj1337 洛谷P1742 用随机增量法.讲解:https://blog.csdn.net/jokerwyt/article/details/79221345 设点集A的最小覆盖圆为g(A) 可 ...
- 洛谷 P2279 [HNOI2003]消防局的设立 (树形dp or 贪心)
一看到这道题就知道是树形dp 之前做过类似的题,只不过保护的范围是1 所以简单很多. 这道题保护的范围是2,就复杂了很多. 我就开始列状态,然后发现竟然有5种 然后我就开始列方程. 但是我考虑的时候是 ...
- 洛谷 P1514 【引水入城】
题库 :洛谷 题号 :1514 题目 :引水入城 link :https://www.luogu.org/problemnew/show/P1514 思路 :搜索从第一排开始能覆盖最后一排的区间L ~ ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
随机推荐
- 清华镜像站安装docker
https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/
- solr 的edismax与dismax比较与分析
edismax支持boost函数与score相乘作为,而dismax只能使用bf作用效果是相加,所以在处理多个维度排序时,score其实也应该是其中一个维度 ,用相加的方式处理调整麻烦. 而disma ...
- git 本地忽略某些个文件
git update-index --assume-unchanged <要忽略的文件> git update-index --no-assume-unchanged <要取消忽略的 ...
- Java文件下载详解
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException ...
- Java_String_Arrays_Character_BigDecimal_Calendar_Math_System
1.String package cn.itcast_01; /* * Scanner:用于接收键盘录入数据. * * 前面的时候: * A:导包 * B:创建对象 * C:调用方法 * * Sy ...
- php 伪协议探究
0x01序 PHP伪协议探究 php中支持的伪协议有下面这么多 file:// — 访问本地文件系统 http:// — 访问 HTTP(s) 网址 ftp:// — 访问 FTP(s) URLs p ...
- IntelliJ IDEA版本控制——过滤提交文件
File——>Settings——>File Types 在ignore files and folders中添加提交是需要忽略的文件 例如:*.iml;*.idea;*.gitignor ...
- web api control注册及重写DefaultHttpControllerSelector、ApiControllerActionSelector、ApiControllerActionInvoker(转)
出处:http://www.cnblogs.com/kingCpp/p/4651154.html namespace EWorkpal.WebApi { public class HttpNotFou ...
- __lll_mutex_lock_wait的错误原因
1. x86_64栈(glib 2.4): free时: (gdb) bt #0 0x00002b9405ea1c38 in __lll_mutex_lock_wait () from /lib64 ...
- 4D(DLG,DRG,DOM,DEM)
基于“倾斜+LiDAR+车载”的实景三维建模实现:链接 MapGIS数据可不可以做到数据融合 遥感影像