bzoj 2823: [AHOI2012]信号塔 最小圆覆盖
题目大意:
给定n个点,求面积最小的园覆盖所有点.其中\(n \leq 10^6\)
题解:
恩。。。
刚拿到这道题的时候...
什么???最小圆覆盖不是\(O(n^3)\)的随机增量算法吗?????
\(10^6\)又是个什么鬼?????????
然后去%了popoqqq大爷的题解...原来这道题数据是随机的啊。。。
随机数据有一个性质,在凸包上的点不超过\(logn\)
所以我们求凸包然后在上面跑随机增量算法即可
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxn = 1000010;
const double eps = 1e-9;
inline int dcmp(const double &x){
if(x < eps && x > -eps) return 0;
return x > 0 ? 1 : -1;
}
struct Point{
double x,y;
Point(const double &a = 0,const double &b = 0){x=a;y=b;}
void print(){
printf("Point : (%lf,%lf)\n",x,y);
}
};
typedef Point Vector;
inline Vector operator + (const Vector &a,const Vector &b){
return Vector(a.x+b.x,a.y+b.y);
}
inline Vector operator - (const Vector &a,const Vector &b){
return Vector(a.x-b.x,a.y-b.y);
}
inline Vector operator / (const Vector &a,const double &b){
return Vector(a.x/b,a.y/b);
}
inline bool operator < (const Point &a,const Point &b){
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline double operator * (const Vector &a,const Vector &b){
return a.x*b.x + a.y*b.y;
}
inline double cross(const Vector &a,const Vector &b){
return a.x*b.y - a.y*b.x;
}
inline double sqr(const double &x){
return x*x;
}
inline double dis(const Point &a,const Point &b){
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}
inline Point getPoint(const Point &p0,const Point &p1,const Point &p2){
double a1 = p1.x - p0.x,b1 = p1.y - p0.y,c1 = (a1*a1 + b1*b1)/2.0;
double a2 = p2.x - p0.x,b2 = p2.y - p0.y,c2 = (a2*a2 + b2*b2)/2.0;
double d = a1*b2 - a2*b1;
return Point(p0.x+(c1*b2-c2*b1)/d,p0.y+(a1*c2-a2*c1)/d);
}
Point o;double r;
inline bool in_cir(const Point &p){
return dcmp(dis(p,o) - r) <= 0;
}
Point p[maxn];int n;
inline void getMinCir(){
o = Point(0,0);r = 0;
for(int i=2;i<=n;++i){
if(!in_cir(p[i])){ o = p[i];r = 0;
for(int j=1;j<i;++j){
if(!in_cir(p[j])){o = (p[i]+p[j])/2.0;r = dis(p[i],o);
for(int k=1;k<j;++k){
if(!in_cir(p[k])){
o = getPoint(p[i],p[j],p[k]);
r = dis(p[i],o);
}
}
}
}
}
}return;
}
Point ch[maxn];int m;
inline void convex(){
sort(p+1,p+n+1);m = 0;
for(int i=1;i<=n;++i){
while(m > 1 && cross(ch[m] - ch[m-1],p[i] - ch[m]) <= 0) -- m;
ch[++m] = p[i];
}int k = m;
for(int i=n-1;i>=1;--i){
while(m > k && cross(ch[m] - ch[m-1],p[i] - ch[m]) <= 0) -- m;
ch[++m] = p[i];
}if(n > 1) -- m;
swap(n,m);swap(p,ch);
}
int main(){
read(n);
for(int i=1;i<=n;++i){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
convex();getMinCir();
printf("%.2lf %.2lf %.2lf\n",o.x,o.y,r);
getchar();getchar();
return 0;
}
bzoj 2823: [AHOI2012]信号塔 最小圆覆盖的更多相关文章
- BZOJ.2823.[AHOI2012]信号塔(最小圆覆盖 随机增量法)
BZOJ 洛谷 一个经典的随机增量法,具体可以看这里,只记一下大体流程. 一个定理:如果一个点\(p\)不在点集\(S\)的最小覆盖圆内,那么它一定在\(S\bigcup p\)的最小覆盖圆上. 所以 ...
- 2018.07.04 BZOJ 2823: AHOI2012信号塔(最小圆覆盖)
2823: [AHOI2012]信号塔 Time Limit: 10 Sec Memory Limit: 128 MB Description 在野外训练中,为了确保每位参加集训的成员安全,实时的掌握 ...
- AHOI2012 信号塔 | 最小圆覆盖模板
题目链接:戳我 最小圆覆盖. 1.枚举第一个点,考虑当前圆是否包含了这个点,如果没有,则把圆变成以这个点为圆心,半径为0的圆. 2.枚举第二个点,考虑圆是否包含了这个点,如果没有,则把圆变成以这两个点 ...
- BZOJ 2823: [AHOI2012]信号塔
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2823 随机增量法.不断加点维护圆,主要是三点共圆那里打得烦(其实也就是个两中垂线求交点+联立方 ...
- 【BZOJ】2823: [AHOI2012]信号塔
题意 给\(n\)个点,求一个能覆盖所有点的面积最小的圆.(\(n \le 50000\)) 分析 随机增量法 题解 理论上\(O(n^3)\)暴力,实际上加上随机化后期望是\(O(n)\)的. 算法 ...
- bzoj2823[AHOI2012]信号塔
2823: [AHOI2012]信号塔 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1190 Solved: 545[Submit][Status ...
- 【BZOJ2823】[AHOI2012]信号塔(最小圆覆盖)
[BZOJ2823][AHOI2012]信号塔(最小圆覆盖) 题面 BZOJ 洛谷 相同的题: BZOJ1 BZOJ2 洛谷 题解 模板题... #include<iostream> #i ...
- BZOJ2823 [AHOI2012]信号塔 【最小圆覆盖】
题目链接 BZOJ2823 题解 最小圆覆盖模板 都懒得再写一次 #include<iostream> #include<cstdio> #include<cmath&g ...
- bzoj2823: [AHOI2012]信号塔&&1336: [Balkan2002]Alien最小圆覆盖&&1337: 最小圆覆盖
首先我写了个凸包就溜了 这是最小圆覆盖问题,今晚学了一下 先随机化点,一个个加入 假设当前圆心为o,半径为r,加入的点为i 若i不在圆里面,令圆心为i,半径为0 再重新从1~i-1不停找j不在圆里面, ...
随机推荐
- mybatis 视频总结
[说明]mabatis卡住了,理解的不深,配置文件的格式太多看不懂(除了连接数据库的部分),听说还可以和log4j集成,怎么个方法 一:今日完成 1)一些语言细节和操作细节 比如在servlet里面操 ...
- 【BZOJ4177】Mike的农场 最小割
[BZOJ4177]Mike的农场 Description Mike有一个农场,这个农场n个牲畜围栏,现在他想在每个牲畜围栏中养一只动物,每只动物可以是牛或羊,并且每个牲畜围栏中的饲养条件都不同,其中 ...
- 新升级!EasyNVR3.0功能概述--直播与录像
背景介绍: 对于摄像机直播已经是我们司空见惯的需求,但是,许多用户在现有的直播的基础上更有录像的需求,并且有关于录像的删除定时等录像计划的需求,更有客户不仅需要这些功能,还需要将这些功能集成到自身的业 ...
- linux集群管理
本文以ubuntu-16.04.3-server-amd64为例,搭建服务器集群.同样是依托于虚拟机. 创建第一个节点 创建新的虚拟机参见:创建新的虚拟机,创建之后,编辑虚拟机,选择Ubuntu镜像, ...
- sgu 1348 Goat in the Garden 2【点到线段的距离】
链接: http://acm.timus.ru/problem.aspx?space=1&num=1348 http://acm.hust.edu.cn/vjudge/contest/view ...
- 从内存中加载并启动一个exe
windows似乎只提供了一种启动进程的方法:即必须从一个可执行文件中加载并启动.而下面这段代码就是提供一种可以直接从内存中启动一个exe的变通办法.用途嘛, 也许可以用来保护你的exe,你可以对要保 ...
- linux c编程:Posix消息队列
Posix消息队列可以认为是一个消息链表. 有足够写权限的线程可以往队列中放置消息, 有足够读权限的线程可以从队列中取走消息 在某个进程往一个队列写入消息前, 并不需要另外某个进程在该队列上等待消息的 ...
- Spring 拦截器——HandlerInterceptor
采用Spring拦截器的方式进行业务处理.HandlerInterceptor拦截器常见的用途有: 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等. 2 ...
- 还原sqlserver2008 r2 数据库步骤
1: 有备份文件bak 文件(是在sqlserver2008 r2上备份的) 数据库下载地址(讯雷) ed2k://|file|cn_sql_server_2008_r2_express_with_m ...
- linux 中 用户管理 (composer 时不能root 遇到)
linux 是支持多用户的,可以同时多个用户在线操作,这点与 Windows 不同. 在我们项目组 操作linux 服务器时,可进行多用户管理,并赋予不同权限,下面是我学习并用的比较频繁的命令: 1. ...