实验报告
课程名称 《算法分析与设计》 实验日期 2020年 4 月 12 日 至 2020 年 4 月 12 日
学生姓名 林泓佺 所在班级 计算机193 学号 20019212212088
实验名称 最近对问题
实验地点 勤园13号楼208 同组人员 林泓佺
1.问题
[给出N个点,求出最近对]
2.解析
[对于N个点求最近对的方法,我们可以采用分治的想法,首先讲所有点按照x轴进行排序,然后从中间一分为二,直到左右区间不可分为止,当只有两个点时,我们可以求出两点距离,再回溯,每次的最小值有三种情况1:都在左区间2、都在右区间3、一个点在左区间,一个点在右区间,所以我们先比较的得到大区间内的左右区间的最小值,再利用最小值将大区间中值两端的离中值小于最小值的点,求出这些点的最近对,然后再和之前的最小值取小值,最后就能求出最小对]
3.设计
[#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct point {
double x,y;
} p[maxn];
int a[maxn];
int cmpxy(point a,point b) {
if(a.xb.x)return a.y<b.y;
return a.x<b.x;
}
int cmpy(int &a,int &b) {
return p[a].y<p[b].y;
}
double dist(point a,point b) {
return sqrt((a.x-b.x)(a.x-b.x)+(a.y-b.y)(a.y-b.y));
}
double closeset(int l, int r) {
if(lr)return 1e8+10;
if(r==l+1)return dist(p[l],p[r]);
int mid=(l+r)>>1;
double ans=min(closeset(l,mid),closeset(mid+1,r));
int cot=0;
for(int i=l; i<=r; i++) {
if(p[mid].x-ans<=p[i].x&&p[i].x<=p[mid].x+ans) {
a[cot++]=i;
}
}
sort(a,a+cot,cmpy);
for(int i=0; i<cot; i++) {
for(int j=i+1; j<cot; j++) {
if(p[a[j]].y-p[a[i]].y>ans)break;
ans=min(dist(p[a[i]],p[a[j]]),ans);
}
}
return ans;
}
int main() {
double minn;
int n;
cin>>n;
for(int i=0; i<n; i++) {
cin>>p[i].x>>p[i].y;
}
sort(p,p+n,cmpxy);
minn=closeset(0, n-1);
printf("%.5lf",minn);
}]
4.分析
[T(n) = O(1) n<2
T(n) = 2T(n/2) + O(n) n>=2
二分递归的复杂度为O(logn)
每次需要n次遍历
复杂度为O(nlogn)]
5.源码
[github源码地址:https://github.com/lhqbalabala/sf4.12]