洛谷 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 ...
随机推荐
- PAT甲级 1155 Heap Paths (30分) 堆模拟
题意分析: 给出一个1000以内的整数N,以及N个整数,并且这N个数是按照完全二叉树的层序遍历输出的序列,输出所有的整条的先序遍历的序列(根 右 左),以及判断整棵树是否是符合堆排序的规则(判断是大顶 ...
- Openstack glance 镜像服务 (五)
Openstack glance 镜像服务 (五) 引用: 官方文档glance安装 https://docs.openstack.org/ocata/zh_CN/install-guide-rdo/ ...
- .NET 5 程序高级调试-WinDbg
上周和大家分享了.NET 5开源工作流框架elsa,程序跑起来后,想看一下后台线程的执行情况.抓了个进程Dump后,使用WinDbg调试,加载SOS调试器扩展,结果无法正常使用了: 0:000> ...
- kubernetes机理之调度器以及控制器
一 了解调度器 1.1 调度器是如何将一个pod调度到节点上的 我们都已然知晓了,API服务器不会主动的去创建pod,只是拉起系统组件,这些组件订阅资源状态的通知,之后创建相应的资源,而负责调度po ...
- pandas数据分析API常用操作
1.导入数据 df = pd.read_csv( # 该参数为数据在电脑中的路径,可以不填写 filepath_or_buffer='/Users/Weidu/Desktop/sz000002.csv ...
- 腾讯云COS对象存储占据数据容灾C位
说到公有云容灾,大家首先想到的是云上数据备份. 然而,随着企业核心业务逐渐从线下迁移到云上,客户提出了更高的要求.如何确保云上业务的高可用.数据的高可靠,这对云厂商提出了新的挑战. 腾讯云作为全球领先 ...
- openshift 3.11安装部署
openshift 3.11 安装部署 openshift安装部署 1 环境准备(所有节点) openshift 版本 v3.11 1.1 机器环境 ip cpu mem hostname OSsys ...
- 18V转5V,18V转3.3V,18V转3V稳压芯片,0.01A-3A输出
18V转5V,18V转3.3V,18V转3V, 18V转5V稳压芯片,18V转3.3V稳压芯片,18V转3V稳压芯片, 18V常降压转成5V电压,3.3V电压和3V电压给其他芯片或设备供电,适用于这个 ...
- Java面向对象(一)----初次见面
面向对象 面向过程:根据业务逻辑从上到下写代码 函数式编程:对一些功能的代码封装到函数中,日后无需重复编写,直接调用函数就可以了 面向对象:将所有的功能进行封装,面对的事封装了功能的实体(对象),即面 ...
- SO_REUSEPORT 使用
https://www.cnblogs.com/Anker/p/7076537.html