数据好水
查看原帖
数据好水
800499
suzhikz楼主2024/9/9 19:28

分治中距离中线的距离小于d忘记加绝对值了也能过属实逆天

感兴趣的可以看代码

#include<bits/stdc++.h>
#define ll long long 
#define reg register
#define db double
#define il inline
using namespace std;
const int N=200005;
int n;
double ans=1e10;
struct node{
	double x,y;
}z[N],book[N];
 int tmp[N];
bool cmp(node a,node b){
	if(a.x!=b.x)
	return a.x<b.x;
	else 
	return a.y<b.y;
}
il double dis(int x,int y){
	return sqrt((z[x].x-z[y].x)*(z[x].x-z[y].x)+(z[x].y-z[y].y)*(z[x].y-z[y].y));
}
double dfs(int l,int r){
	if(l==r)return 1e10;
	if(l==r-1){
		ans=min(ans,dis(l,r));
		if(z[l].y>z[r].y)swap(z[l],z[r]);
		return dis(l,r);
	}
	int mid=(l+r)/2;
	double a=z[mid].x;
	double d=min(dfs(l,mid),dfs(mid+1,r));
	int tot=0;
	int c=l,dd=mid+1,cnt=l-1;
	while(c<=mid&&dd<=r){
		if(z[c].y>z[dd].y){
			book[++cnt]=z[dd++];
		}else{
			book[++cnt]=z[c++];
		}
	}
	if(c<=mid){
		while(c<=mid)book[++cnt]=z[c++];
	}else if(dd<=r){
		while(dd<=r)book[++cnt]=z[dd++];
	}
	for(reg int i=l;i<=r;i++)z[i]=book[i];
	cnt=0;
	for(reg int i=l;i<=r;i++){
		if(a-z[i].x<d)tmp[++cnt]=i;
	}
	for(reg int i=1;i<=cnt;i++){
		for(reg int j=i+1;j<=cnt&&z[tmp[j]].y-z[tmp[i]].y<d;j++){
			d=min(d,dis(tmp[i],tmp[j]));
		}
	}
	ans=min(ans,d);
	return d;
}
int main(){
	scanf("%d",&n);
	for(register int i=1;i<=n;i++){
		scanf("%lf%lf",&z[i].x,&z[i].y);
	}
	sort(z+1,z+1+n,cmp);
	dfs(1,n);
	printf("%.4lf",ans);
	return 0;
}
2024/9/9 19:28
加载中...