1

There a set A with n 3d points (x,y,z) and set B with m 3d points (x,y,z). For each point (Xi,Yi,Zi) in set A we have to find a point in set B that has minimum distance from (Xi,Yi,Zi).

My code is running out of given time limit. Please help.

#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;
}
Sirko
  • 72,589
  • 19
  • 149
  • 183
hell coder
  • 93
  • 1
  • 7

2 Answers2

2

You're using an O(n^2) algo. I doubt that is fast enough. For some ways to do it faster, check out this article.

Or more specifically, you can use the divide an conquer approach described in that article, which is relatively straightforward if you're comfortable with recursion. Since you are dealing with z axis, you'll have to extend the algo described there to use 2 dividing lines (one for x axis, then one for y), so it's going to be a bit more complicated.

dcp
  • 54,410
  • 22
  • 144
  • 164
0

One approach would be to create a nearest neighbour triangulation from either set which is O(n log n), then use something like a proximity search to drape each point in turn from the other set onto the triangulation to find it's nearest neighbour. For doing this type of thing in C, Joseph O'Rourkes book is going to be well worth reading.

SmacL
  • 22,555
  • 12
  • 95
  • 149