社区讨论

求助一道acwing的题

学术版参与者 2已保存回复 3

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lo82g072
此快照首次捕获于
2023/10/27 11:40
2 年前
此快照最后确认于
2023/10/27 11:40
2 年前
查看原帖
这题数据有点毒瘤,一直TLE。但加了随机数就过了。
原版:
CPP
#include<bits/stdc++.h>
using namespace std;
struct node {
	double x,y;
	bool k;
	bool operator<(const node &a) const{
		return x<a.x;
	}
}a[210000],tmp[210000];
const double INF=1e15;
double dis(node x,node y) {
	if(x.k==y.k) return INF;
	double xx=x.x-y.x,yy=x.y-y.y;
	return sqrt(xx*xx+yy*yy);
}
double dfs(int l,int r) {
	if(l==r) return INF;
	int mid=(l+r)>>1;
	double mid_x=a[mid].x;
	double ans=min(dfs(l,mid),dfs(mid+1,r));
	int i=l,j=mid+1,tlen=0;
	while(i<=mid&&j<=r) {
		if(a[i].y<a[j].y) tmp[++tlen]=a[i++];
		else tmp[++tlen]=a[j++];
	}
	while(i<=mid) tmp[++tlen]=a[i++];
	while(j<=r) tmp[++tlen]=a[j++];
	for(i=l;i<=r;i++) a[i]=tmp[i-l+1];
	tlen=0;
	for(i=l;i<=r;i++) {
		if(abs(a[i].x-mid_x)<ans) {
			tmp[++tlen]=a[i];
		}
	}
	for(i=1;i<=tlen;i++) {
		for(j=i-1;j>=1&&tmp[i].y-tmp[j].y<ans;j--) {
			ans=min(ans,dis(tmp[i],tmp[j]));
		}
	}
	return ans;
}
int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) {
			scanf("%lf%lf",&a[i].x,&a[i].y);
			a[i].k=0;
		}
		for(int i=n+1;i<=(n<<1);i++) {
			scanf("%lf%lf",&a[i].x,&a[i].y);
			a[i].k=1; 
		}
		sort(a+1,a+1+(n<<1));
		printf("%.3lf\n",dfs(1,n<<1));
	}
}
AC的版本:
CPP
#include<bits/stdc++.h>
using namespace std;
struct node {
	double x,y;
	bool k;
	int rd;
	bool operator<(const node &a) const{
		if(x==a.x) return rd<a.rd;
		return x<a.x;
	}
}a[210000],tmp[210000];
const double INF=1e15;
double dis(node x,node y) {
	if(x.k==y.k) return INF;
	double xx=x.x-y.x,yy=x.y-y.y;
	return sqrt(xx*xx+yy*yy);
}
double dfs(int l,int r) {
	if(l==r) return INF;
	int mid=(l+r)>>1;
	double mid_x=a[mid].x;
	double ans=min(dfs(l,mid),dfs(mid+1,r));
	int i=l,j=mid+1,tlen=0;
	while(i<=mid&&j<=r) {
		if(a[i].y<a[j].y) tmp[++tlen]=a[i++];
		else tmp[++tlen]=a[j++];
	}
	while(i<=mid) tmp[++tlen]=a[i++];
	while(j<=r) tmp[++tlen]=a[j++];
	for(i=l;i<=r;i++) a[i]=tmp[i-l+1];
	tlen=0;
	for(i=l;i<=r;i++) {
		if(abs(a[i].x-mid_x)<ans) {
			tmp[++tlen]=a[i];
		}
	}
	for(i=1;i<=tlen;i++) {
		for(j=i-1;j>=1&&tmp[i].y-tmp[j].y<ans;j--) {
			ans=min(ans,dis(tmp[i],tmp[j]));
		}
	}
	return ans;
}
int main() {
	srand(20081124);
	int T;
	scanf("%d",&T);
	while(T--) {
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++) {
			scanf("%lf%lf",&a[i].x,&a[i].y);
			a[i].k=0;
			a[i].rd=rand()%100000;
		}
		for(int i=n+1;i<=(n<<1);i++) {
			scanf("%lf%lf",&a[i].x,&a[i].y);
			a[i].k=1; 
			a[i].rd=rand()%100000;
		}
		sort(a+1,a+1+(n<<1));
		printf("%.3lf\n",dfs(1,n<<1));
	}
}

回复

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

正在加载回复...