有一个具有n个3d点(x,y,z)的集合A和具有m个3d点(x,y,z)的集合B. 对于集合A中的每个点(Xi,Yi,Zi),我们必须找到集合B中与(Xi,Yi,Zi)的距离最小的点。
我的代码超出了给定的时间限制。请帮忙。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
long long np[50000][3],qp[50000][3];
int main()
{
long long n,q,i,j,d,ans,min;
scanf("%lld",&n);
for(i=0;i<n;i++)
scanf("%lld%lld%lld",&np[i][0],&np[i][0],&np[i][2]);
scanf("%lld",&q);
for(i=0;i<q;i++)
scanf("%lld%lld%lld",&qp[i][0],&qp[i][1],&qp[i][2]);
for(i=0;i<q;i++)
{
ans=0;
min=((qp[i][0]-np[0][0])*(qp[i][0]-np[0][0]))+((qp[i][1]-np[0][1])*(qp[i][1]-qp[0][1]))+((qp[i][2]-np[0][2])*(qp[i][2]-np[0][2]));
for(j=0;j<n;j++)
{
d=((qp[i][0]-np[j][0])*(qp[i][0]-np[j][0]))+((qp[i][1]-np[j][1])*(qp[i][1]-qp[j][1]))+((qp[i][2]-np[j][2])*(qp[i][2]-np[j][2]));
if(d<min)
{
ans=j;
min=d;
}
}
printf("%lld\n",ans);
}
return 0;
}
答案 0 :(得分:2)
你正在使用O(n ^ 2)算法。我怀疑这是否足够快。有些方法可以更快地完成,请查看this article。
或者更具体地说,您可以使用该文章中描述的分治方法,如果您对递归感到满意,这种方法相对简单。由于你正在处理z轴,你必须扩展那里描述的算法使用2个分界线(一个用于x轴,然后一个用于y),所以它会更复杂一些。
答案 1 :(得分:0)
一种方法是从任一组创建nearest neighbour triangulation,即O(n log n),然后使用像proximity search这样的东西将每个点从另一个集合依次覆盖到三角剖分上找到它最近的邻居。对于在C中执行此类操作,Joseph O'Rourkes book将非常值得一读。