P1429 平面最近点对(加强版)(分治)
2024-10-08 15:30:58
主要思路:
分治,将点按横坐标为第1关键字升序排列,纵坐标为第2关键字升序排列,进入左半边和右半边进行分治。
设d为左右半边的最小点对值。然后以mid这个点为中心,扩展宽为2d,长为2d的正方形。除了这个正方形外的点都不可能使答案更小。而且这个正方形里至多8个点(可以证明至多6个,我不会。but,知道至多8个就够了,这样已经保证了复杂度。)一句话证明:如果多余8个点,那么必有2个点的最小距离比d小。这8个点内暴力枚举就好了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1000005;
const double inf=1e12;
struct node{
double x,y;
}p[N];
bool cmp(node a,node b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
bool cmp2(int a,int b)
{
return p[a].y<p[b].y;
}
double dist(int a,int b){return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));}
int n,a[N];
double msort(int l,int r)
{
double d=inf;
if(l==r)return d;
if(l==r-1)return dist(l,r);
int mid=l+r>>1;
double d1=msort(l,mid);
double d2=msort(mid+1,r);
d=min(d1,d2);
int cnt=0;
for(int i=l;i<=r;i++)
if(fabs(p[i].x-p[mid].x)<=d)a[++cnt]=i;
sort(a+1,a+cnt+1,cmp2);
for(int i=1;i<=cnt;i++)
{
for(int j=i+1;j<=cnt&&fabs(p[a[i]].y-p[a[j]].y)<d;j++)
{
d=min(d,dist(a[i],a[j]));
}
}
return d;
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp);
printf("%.4lf\n",msort(1,n));
return 0;
}
最新文章
- 【Beta版本】冲刺-Day7
- 彻底解决Google浏览器CSS居中问题
- MySQL慢日志监控脚本实例剖析
- 从0开始学java——JUnit4 复习,其实基本思想还是那些,不过采用了新的注释格式的语法
- MyEclipse 安装目录下找不到Common目录
- 【Xamarin破解补丁找不到?】
- 模拟JQUERY的延迟方法绑定
- &ldquo;找回&rdquo; Envi 快捷方式
- Android---Parcelable包装类的作用
- [array] leetcode - 54. Spiral Matrix - Medium
- JVM核心之JVM运行和类加载全过程
- Java中,多态的实现有哪些要求?实现多态的关键技术?
- 位(bit)、字节(byte)、字符、编码之间的关系
- 微信支付异常:appid and openid not match
- How does exercise keep your brain young?
- Ado.net和EF的区别
- 安装cactiez v11对windows和linux系统进行监控
- Auto Encoder用于异常检测
- python 26个技巧
- ovs QOS
热门文章
- Duilib程序添加托盘图标显示
- 【PAT甲级】1036 Boys vs Girls (25 分)
- Codeforces Round #581 (Div. 2)D(思维,构造,最长非递减01串)
- Controller 层类
- Windows Android SDK下载安装,配置,异常问题解决教程
- Codeforces1303E. Erase Subsequences
- MYSQL--“Row size too large (>; 8126)”
- Autoit里用多进程模拟多线程
- 思科 ASA 系列防火墙 官方文档下载指南
- ES6之新的数据结构