P1429 平面最近点对 分治做法91pts WA 求助
  • 板块学术版
  • 楼主Reunite
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/12/22 11:47
  • 上次更新2023/10/24 06:58:01
查看原帖
P1429 平面最近点对 分治做法91pts WA 求助
377760
Reunite楼主2022/12/22 11:47

一道分治的经典题,我用的是分治。

第8个点WA了,并且误差大的离谱。

求调

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int n;
struct node{double x,y;int id;};
node a[200005];
node b[200005];
int bin[200005];
int inb[200005];
int bn[200005];
int lin[200005];
int rin[200005];

inline void in(double &n){
	n=0;
	char c=getchar();
	while(c<'0' || c>'9') c=getchar();
	while(c>='0'&&c<='9') n=n*10+c-'0',c=getchar();
	if(c!='.') return ;
	double x=1;
	c=getchar();
	while(c>='0'&&c<='9') n+=0.1*x*(c-'0'),c=getchar(),x*=0.1;
	return ;
}

bool cmp(node p,node q){return p.x==q.x?p.y<q.y:p.x<q.x;}
bool cmp2(node p,node q){return p.y==q.y?p.x<q.x:p.y<q.y;}

inline double dis(int i,int j){return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));}

double solve(int l,int r){
	if(l+1==r) return dis(l,r);
	if(l+2==r) return min(min(dis(l,l+1),dis(l,r)),dis(l+1,r));
	int mid=l+r>>1;
	double dd=min(solve(l,mid),solve(mid+1,r)),md=a[mid].x;
	int ls=0,rs=0;
	for(int i=l;i<=mid;i++)
		if(md-a[i].x<=dd) lin[++ls]=bn[i];
	for(int i=mid+1;i<=r;i++)
		if(a[i].x-md<=dd) rin[++rs]=bn[i];
	if(ls==0||rs==0) return dd;
	int rt=1;
	double ddd=2e9;
	for(int i=1;i<=ls;i++){
		while(b[rin[rt]].y<=b[lin[i]].y&&b[lin[i]].y-b[rin[rt]].y>dd&&rt<rs) rt++;
		for(int j=rt;j<=min(rt+10,rs);j++)
			ddd=min(ddd,sqrt((b[lin[i]].x-b[rin[j]].x)*((b[lin[i]].x-b[rin[j]].x))+(b[lin[i]].y-b[rin[j]].y)*(b[lin[i]].y-b[rin[j]].y)));
	}
	return min(dd,ddd);
}

int main(){
//	freopen("qwq.in","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;i++) in(a[i].x),in(a[i].y),a[i].id=i,b[i]=a[i];
//	for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y),a[i].id=i,b[i]=a[i];
	sort(a+1,a+1+n,cmp);
	for(int i=2;i<=n;i++)
		if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y){
			printf("0.0000");
			return 0;
		}
	sort(b+1,b+1+n,cmp2);
	for(int i=1;i<=n;i++) bin[a[i].id]=i,inb[b[i].id]=i;
	for(int i=1;i<=n;i++) bn[bin[i]]=inb[i];
	printf("%.4lf",solve(1,n));
	
	return 0;
} 
2022/12/22 11:47
加载中...