社区讨论

关于如何将 sort 换成归并排序

P1429平面最近点对(加强版)参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mhja1gh6
此快照首次捕获于
2025/11/03 23:10
4 个月前
此快照最后确认于
2025/11/03 23:10
4 个月前
查看原帖
RT,这里算法实现参照题解二
CPP
#include <bits/stdc++.h>
using namespace std;

using ld = long double;
using ll = long long;
typedef struct Point { ld x; ld y; } Pt;
const int maxn = 2e5+5;
const ld inf = 2 << 20;

bool cmp(const Pt &a, const Pt &b){
	if(a.x==b.x) return a.y<b.y;
	else return a.x<b.x;
}

ld dist(Pt i, Pt j) 
{
    ld x = (i.x - j.x) * (i.x - j.x);
	ld y = (i.y - j.y) * (i.y - j.y);
    return sqrt(x + y);
}

Pt p[maxn];
int tmp[maxn];
int n;

ld merge(int l, int r){
	if(l==r) return inf;
	else if(l+1==r) return dist(p[l],p[r]);
	int mid = l+r>>1;
	ld d1 = merge(l,mid), d2 = merge(mid+1,r);
	ld d = min(d1,d2);
	int tp=0; 
	for(int i = l; i<=r; i++){
		if(fabs(p[mid].x-p[i].x) < d) tmp[++tp] = i;
	}
	stable_sort(tmp+1,tmp+1+tp,[](int a, int b){ return p[a].y < p[b].y; }); // sort here !!!
	for(int i = 1; i<=tp; i++){
		for(int j = i+1; (j<=tp)&&(p[tmp[j]].y-p[tmp[i]].y < d); j++){
			ld d3 = dist(p[tmp[j]],p[tmp[i]]);
			d=min(d,d3);
		}
	}
	return d;
}

int main(){
	cin>>n;
	for(int i = 1; i<=n; i++) cin>>p[i].x>>p[i].y;
	stable_sort(p+1,p+1+n,cmp);
	return printf("%.4Lf",merge(1,n)), 0;
}
在上述代码注释处,题解指出了我们可以用归并排序替换掉 sort/stable_sort
但是我有一个疑惑的点,这个 tmp 数组需要在分治 merge(l,mid)merge(mid+1,r) 结束后才能根据 d=min(d1,d2) 的值确定,但是归并排序需要我们在分治的过程中就把左右两端排好序,那么如何在分治结束后对 tmp 数组的左右两部分排序,换言之,我们怎么在 tmp 数组诞生前就把这两段排好序()
机房同学觉得我太唐了不愿意回答我qwq

回复

2 条回复,欢迎继续交流。

正在加载回复...