Luogu P1429 平面最近点对(加强版)(分治)
题意
题目描述
给定平面上\(n\)个点,找出其中的一对点的距离,使得在这\(n\)个点的所有点对中,该距离为所有点对中最小的。
输入输出格式
输入格式:
第一行:\(n\);\(2\leq n\leq 200000\)
接下来\(n\)行:每行两个实数:\(x\ y\),表示一个点的行坐标和列坐标,中间用一个空格隔开。
输出格式:
仅一行,一个实数,表示最短距离,精确到小数点后面\(4\)位。
输入输出样例
输入样例#1:
3
1 1
1 2
2 2
输出样例#1:
1.0000
说明
\(0\leq x,y\leq 10^9\)
思路
利用分治的方法实现。我们先把所有点按照横坐标排序,然后查询每一个区间的最近点对距离。假设当前查询的是\([l,r]\)区间的最近点对距离,那么这个区间的答案就在\([l,mid]\)区间的最近点对距离、\([mid+1,r]\)区间的最近点对距离、靠近中间的分别在两个区间中的一些点之间的距离中产生,我们主要考虑第三部分答案如何统计。
首先通过分治,我们已经求出了左右两区间的最近点对距离\(min\),接下来找到\([l,r]\)区间内横坐标与\(mid\)的横坐标相差不超过\(min\)的点,并将这些点两两匹配求出最近距离。这样能保证答案的正确性,但是时间复杂度呢?据说这样子做的时间复杂度是\(O(n\log n)\)的,所以也不用担心超时的问题。
AC代码
#include<bits/stdc++.h>
using namespace std;
int n;
struct Point
{
double x,y;
bool operator < (const Point &sjf){return x<sjf.x;}
}p[200005],q[200005];
double devide(int l,int r)
{
if(l==r) return DBL_MAX;
else if(l+1==r) return sqrt((p[l].x-p[r].x)*(p[l].x-p[r].x)+(p[l].y-p[r].y)*(p[l].y-p[r].y));
int mid=(l+r)>>1,cnt=0;
double d=min(devide(l,mid),devide(mid+1,r));
for(int i=l;i<=r;i++) if(fabs(p[i].x-p[mid].x)<=d) q[++cnt]=p[i];
for(int i=1;i<=cnt;i++)
for(int j=i+1;j<=cnt&&fabs(q[i].x-q[j].x)<=d;j++)
d=min(d,sqrt((q[i].x-q[j].x)*(q[i].x-q[j].x)+(q[i].y-q[j].y)*(q[i].y-q[j].y)));
return d;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1);
printf("%.4f",devide(1,n));
return 0;
}
Luogu P1429 平面最近点对(加强版)(分治)的更多相关文章
- Luogu P1429 平面最近点对 【分治】By cellur925
题目传送门 题目大意:给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的.$n$<=100000. $Algorithm$ 最朴素的$n^2$枚举肯定 ...
- P1429 平面最近点对[加强版] 随机化
LINK:平面最近点对 加强版 有一种分治的做法 因为按照x排序分治再按y排序 可以证明每次一个只会和周边的六个点进行更新. 好像不算很难 这里给出一种随机化的做法. 前置知识是旋转坐标系 即以某个点 ...
- P1429 平面最近点对(加强版)(分治)
P1429 平面最近点对(加强版) 主要思路: 分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治. 设d为左右半边的最小点对值.然后以mid这个点为中心, ...
- Luogu 1429 平面最近点对 | 平面分治
Luogu 1429 平面最近点对 题目描述 给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的 输入输出格式 输入格式: 第一行:n:2≤n≤200000 ...
- Vijos 1012 清帝之惑之雍正 平面最近点对(分治)
背景 雍正帝胤祯,生于康熙十七年(1678)是康熙的第四子.康熙61年,45岁的胤祯继承帝位,在位13年,死于圆明园.庙号世宗. 胤祯是在康乾盛世前期--康熙末年社会出现停滞的形式下登上历史舞台的.复 ...
- 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...
- 洛谷 P1429 平面最近点对(加强版) (分治模板题)
题意:有\(n\)个点对,找到它们之间的最短距离. 题解:我们先对所有点对以\(x\)的大小进行排序,然后分治,每次左右二等分递归下去,当\(l+1=r\)的时候,我们计算一下距离直接返回给上一层,若 ...
- p1429 平面最近点对(加强版)
传送门 分析 我们可以枚举每一个点算它的最近点 估价函数应该分为3种情况计算: 大于max,小于min,位于min和max之间 代码 #include<iostream> #include ...
- (洛谷 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 ...
随机推荐
- RAKsmart服务器受消费者青睐的原因
随着互联网的快速发展,网站建设变得越来越重要,现在很多做外贸网站的都会选择美国服务器来建设网站,近年来RAKsmart服务器受到广大站长的欢迎,那RAKsmart服务器受消费者青睐的关键是什么呢. 1 ...
- C++: string<-->char
1. char*.char[] 与 std::string 之间的区别: char*是一个指向字符的指针,是一个内置类型.可以指向一个字符,也可以表示字符数组的首地址(首字符的地址).我们更多的时候是 ...
- A decorative fence
A decorative fence 在\(1\sim n\)的全排列\(\{a_i\}\)中,只有大小交错的(即任意一个位置i满足\(a_{i-1}<a_i>a_{i+1}ora_{i- ...
- 帆软报表PC端实施报表心得体会
1.报表制作完成后,预览时自动显示查询内容,在控件处设置: 2.求一列数据的最小值(除去0),并对最小值字体加粗标绿,需要对对应单元格设置条件属性,并插入公式:C6 = min(greparray(C ...
- Windows tasklist
TASKLIST [/S system [/U username [/P [password]]]] [/M [module] | /SVC | /V] [/FI filter] [/ ...
- 剑指Offer-16:合并两个有序链表
题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 例如A链表为1-3-5-7,B链表为2-4-6-8.所以合并后的新链表C为1-2-3-4-5- ...
- tomcat7 linux service
1. 创建tomcat用户 useradd -r -m -d /usr/local/tomcat7 -s /sbin/nologin tomcat 2. 将下面脚本命名为tomcat7 放入/etc/ ...
- VS2010-MFC(MFC常用类:CString类)
转自:http://www.jizhuomi.com/software/228.html CString类简介 CString类作为MFC的常用类,当之无愧.可以这样说,只要是从事MFC开发,基本都会 ...
- idea从github中pull或者push成功之后tomcat启动不了,报Error....
解决方案:删除deployment里面的war包,确定. 再在deployment里面重新添加一个war包,确定,即可.
- java编程规约三
七.集合处理 1.尽量使用String对象做Map的key 2.list转数组,用list的toArray(T[] array),传入的参数array是类型完全一样的数组,大小是list.size() ...