洛谷 P1429 平面最近点对(加强版) (分治模板题)
题意:有\(n\)个点对,找到它们之间的最短距离.
题解:我们先对所有点对以\(x\)的大小进行排序,然后分治,每次左右二等分递归下去,当\(l+1=r\)的时候,我们计算一下距离直接返回给上一层,若\(l==r\)说明只有一个点,不能构成线段,返回\(INF\),于是当前区间的左右两边的最短距离我们找到了,之后还有一种情况,就是一个点在\(mid\)左边,一个在\(mid\)右边,由于左右两边的最短距离\(d\)已知,所以我们可以再划分一个区间\([mid-d,mid+d]\),容易证明,若最短距离横穿\(mid\)线的话,两点一定在这个区间内,我们用\(tmp\)数组记录区间内的点,然后再枚举这些点求它们的距离,但是这里要优化一下,假如它们之间纵坐标的距离>\(d\),那么一定是不合法的,具体细节见代码.
代码:
struct misaka{
double x,y;
}e[N],tmp[N]; int n; bool cmp1(misaka a,misaka b){
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
} bool cmp2(misaka a,misaka b){
if(a.y==b.y) return a.x<b.x;
return a.y<b.y;
} double dis(misaka a,misaka b){ //求距离
double res=fabs(a.x-b.x)*fabs(a.x-b.x)+fabs(a.y-b.y)*fabs(a.y-b.y);
return sqrt(res);
} double MIN(double a,double b){ //手写求min
if(a>b) return b;
else return a;
} double merge(int l,int r){
if(l==r) return INF; //只有一个点
if(l+1==r) return dis(e[l],e[r]); //递归边界,直接返回给上一层
int mid=(l+r)>>1;
int cnt=0;
double d=MIN(merge(l,mid),merge(mid+1,r)); //求左边和右边的最小距离
for(int i=l;i<=r;++i){
if(fabs(e[mid].x-e[i].x)<=d){ //判断点是否在[mid-x,mid+x]内
tmp[++cnt]=e[i];
}
}
sort(tmp+1,tmp+1+cnt,cmp2); //按纵坐标排序
for(int i=1;i<=cnt;++i){
for(int j=i+1;j<=cnt && fabs(tmp[i].y-tmp[j].y)<=d;++j){ //若纵坐标的差大于d,直接下一个点
d=MIN(d,dis(tmp[i],tmp[j]));
}
}
return d;
} int main() {
//ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%lf %lf",&e[i].x,&e[i].y); sort(e+1,e+1+n,cmp1); double ans=merge(1,n); printf("%.4f\n",ans); return 0;
}
洛谷 P1429 平面最近点对(加强版) (分治模板题)的更多相关文章
- (洛谷 P1429 平面最近点对(加强版) || 洛谷 P1257 || Quoit Design HDU - 1007 ) && Raid POJ - 3714
这个讲的好: https://phoenixzhao.github.io/%E6%B1%82%E6%9C%80%E8%BF%91%E5%AF%B9%E7%9A%84%E4%B8%89%E7%A7%8D ...
- P1429 平面最近点对[加强版] 随机化
LINK:平面最近点对 加强版 有一种分治的做法 因为按照x排序分治再按y排序 可以证明每次一个只会和周边的六个点进行更新. 好像不算很难 这里给出一种随机化的做法. 前置知识是旋转坐标系 即以某个点 ...
- 洛谷1429 平面最近点对(KDTree)
qwq(明明可以直接分治过掉的) 但是还是当作联系了 首先,对于这种点的题,很显然的套路,我们要维护一个子树\(mx[i],mn[i]\)分别表示每个维度的最大值和最小值 (这里有一个要注意的东西!就 ...
- Luogu P1429 平面最近点对 【分治】By cellur925
题目传送门 题目大意:给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的.$n$<=100000. $Algorithm$ 最朴素的$n^2$枚举肯定 ...
- Luogu P1429 平面最近点对(加强版)(分治)
P1429 平面最近点对(加强版) 题意 题目描述 给定平面上\(n\)个点,找出其中的一对点的距离,使得在这\(n\)个点的所有点对中,该距离为所有点对中最小的. 输入输出格式 输入格式: 第一行: ...
- P1429 平面最近点对(加强版)(分治)
P1429 平面最近点对(加强版) 主要思路: 分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治. 设d为左右半边的最小点对值.然后以mid这个点为中心, ...
- Vijos 1012 清帝之惑之雍正 平面最近点对(分治)
背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...
- 洛谷P1067 多项式输出 NOIP 2009 普及组 第一题
洛谷P1067 多项式输出 NOIP 2009 普及组 第一题 题目描述 一元n次多项式可用如下的表达式表示: 输入输出格式 输入格式 输入共有 2 行 第一行 1 个整数,n,表示一元多项式的次数. ...
- 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...
随机推荐
- TCP/IP五层模型-传输层-UDP协议
1.定义:UDP:是非面向连接.不可靠的用户数据包协议. 2.应用场景:适合对数据完整性要求不高,但对延迟很敏感,比如即时通信(语音视频聊天等). 3.UDP报文格式: 4.用UDP传输数据的应用层 ...
- 原生工程接入Flutter实现混编
前言 上半年我定的OKR目标是帮助团队将App切入Flutter,实现统一技术栈,变革成多端融合开发模式.Flutter目前是跨平台方案中最有潜力实现我们这个目标的,不管是Hybird还是React ...
- 目前用下来最溜的MacOS微信多开工具!
一个生活微信,一个工作微信是很多上班族的基本配置. 但由于微信客户端在PC端上只能打开一个,这使得在上班时候就非常不便,一个号在PC端上登录,一个在手机上使用,但是上班时候又不能一直看手机,不然老板还 ...
- libnum报错问题解决
之前在使用python libnum库时报错 附上报错内容 Traceback (most recent call last) : File" D:/python file/ctf/RSA共 ...
- linux系统中set、env、export关系
set 用来显示shell变量(包括环境变量.用户变量和函数名及其定义),同时可以设置shell选项来开启调试.变量扩展.路径扩展等开关env 用来显示和设置环境变量export 用来显示和设置导出到 ...
- 记录Js动态加载页面.append、html、appendChild、repend添加元素节点不生效以及解决办法
今天再优化blog页面的时候添加了个关注按钮和图片,但是页面上这个按钮和图片时有时无,本来是搞后端的,被这个前端的小问题搞得抓耳挠腮的! 网上各种查询解决方案,把我解决问题的艰辛历程分享出来,希望大家 ...
- python异步回调顺序?是否加锁?
话不多说,直接上代码: import time from functools import partial from concurrent.futures.process import Process ...
- MySQL ---- 锁知识
锁 我们知道mysql中支持很多个存储引擎,在不同的存储引擎下所能支持的锁是不同的,我们通过MyISAM和InnoDB来进行一下对比. 表级锁定(table-level) 表级别的锁定是MySQL ...
- Databricks 第9篇:Spark SQL 基础(数据类型、NULL语义)
Spark SQL 支持多种数据类型,并兼容Python.Scala等语言的数据类型. 一,Spark SQL支持的数据类型 整数系列: BYTE, TINYINT:表示1B的有符号整数 SHORT, ...
- ES数据库高可用配置
ES高可用集群部署 1.ES高可用架构图 2.创建ES用户组 1.Elasticsearch不能在 root 用户下启动,我们需要在三台机器上分创建一个普通用户# 创建elastic用户 userad ...