最近的一对SPOJ logN时间错误答案

时间:2014-02-22 13:16:34

标签: c++ algorithm sorting closest

我正在努力解决这个问题。 http://www.spoj.com/problems/CLOPPAIR/
我的主要想法是将坐标分成几部分,在同一部分中所有点都具有相同的x。按x和y对所有坐标进行排序。
我什么时候检查哪个点最接近Ni,我会将它与更高的y相同的x和更低的y以及相同的x进行比较。我还将尝试在x坐标的前一部分中搜索并使用二分搜索搜索它们,我也将搜索x坐标的下一部分。
但我总是得到错误的答案。任何人都可以告诉我有什么问题。代码如下。

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <utility>
#include <map>
#include <vector>
using namespace std;
typedef pair<int,int>par;
typedef long long int ll;
par niz[55000];
map<ll,ll>mapa2;
map<par,ll>mapa;
map<ll,ll>mapa3;
vector<par>V[55000];
ll a,b,c,d,e,f;
double euk=1561561616;
ll toc=0,toc2=0;
ll pos1=1,pos2;
void binary(ll pos,ll end)
{
     if(pos<pos1-1)
     {

      ll tockay=V[pos][end].second;
      ll low=0;
      ll high=V[pos+1].size();
      ll midd=0;
      while(low<=high)
      {
         midd=(low+high)/2;
         if(V[pos+1][midd].second>tockay)high=midd-1;
         else low=midd+1;
      }
      if(euk>sqrt((V[pos][end].first-V[pos+1][midd].first)*(V[pos][end].first-V[pos+1][midd].first)+(V[pos][end].second-V[pos+1][midd].second)*(V[pos][end].second-V[pos+1][midd].second)))
      {
        euk=sqrt((V[pos][end].first-V[pos+1][midd].first)*(V[pos][end].first-V[pos+1][midd].first)+(V[pos][end].second-V[pos+1][midd].second)*(V[pos][end].second-V[pos+1][midd].second));
        toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
        toc2=mapa[make_pair(V[pos+1][midd].first,V[pos+1][midd].second)];
      }
      if(midd-1>=0)
      {
         if(euk>sqrt((V[pos][end].first-V[pos+1][midd-1].first)*(V[pos][end].first-V[pos+1][midd-1].first)+(V[pos][end].second-V[pos+1][midd-1].second)*(V[pos][end].second-V[pos+1][midd-1].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos+1][midd-1].first)*(V[pos][end].first-V[pos+1][midd-1].first)+(V[pos][end].second-V[pos+1][midd-1].second)*(V[pos][end].second-V[pos+1][midd-1].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos+1][midd-1].first,V[pos+1][midd-1].second)];
         } 
      }
      if(midd-2>=0)
      {
         if(euk>sqrt((V[pos][end].first-V[pos+1][midd-2].first)*(V[pos][end].first-V[pos+1][midd-2].first)+(V[pos][end].second-V[pos+1][midd-2].second)*(V[pos][end].second-V[pos+1][midd-2].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos+1][midd-2].first)*(V[pos][end].first-V[pos+1][midd-2].first)+(V[pos][end].second-V[pos+1][midd-2].second)*(V[pos][end].second-V[pos+1][midd-2].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos+1][midd-2].first,V[pos+1][midd-2].second)];
         } 
      }
      if(midd+1<V[pos+1].size())
      {
         if(euk>sqrt((V[pos][end].first-V[pos+1][midd+1].first)*(V[pos][end].first-V[pos+1][midd+1].first)+(V[pos][end].second-V[pos+1][midd+1].second)*(V[pos][end].second-V[pos+1][midd+1].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos+1][midd+1].first)*(V[pos][end].first-V[pos+1][midd+1].first)+(V[pos][end].second-V[pos+1][midd+1].second)*(V[pos][end].second-V[pos+1][midd+1].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos+1][midd+1].first,V[pos+1][midd+1].second)];
         } 
      } 
      if(midd+2<V[pos+1].size())
      {
         if(euk>sqrt((V[pos][end].first-V[pos+1][midd+2].first)*(V[pos][end].first-V[pos+1][midd+2].first)+(V[pos][end].second-V[pos+1][midd+2].second)*(V[pos][end].second-V[pos+1][midd+2].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos+1][midd+2].first)*(V[pos][end].first-V[pos+1][midd+2].first)+(V[pos][end].second-V[pos+1][midd+2].second)*(V[pos][end].second-V[pos+1][midd+2].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos+1][midd+2].first,V[pos+1][midd+2].second)];
         } 
      }                      
     }
     //prllf("hhkhj %d\n",pos);
     if(pos!=1)
     {

      ll tockay=V[pos][end].second;
      ll low=0;
      ll high=V[pos-1].size();
      ll midd=0;
      while(low<=high)
      {
         midd=(low+high)/2;
         if(V[pos-1][midd].second>tockay)high=midd-1;
         else low=midd+1;
      }
      if(euk>sqrt((V[pos][end].first-V[pos-1][midd].first)*(V[pos][end].first-V[pos-1][midd].first)+(V[pos][end].second-V[pos-1][midd].second)*(V[pos][end].second-V[pos-1][midd].second)))
      {
        euk=sqrt((V[pos][end].first-V[pos-1][midd].first)*(V[pos][end].first-V[pos-1][midd].first)+(V[pos][end].second-V[pos-1][midd].second)*(V[pos][end].second-V[pos-1][midd].second));
        toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
        toc2=mapa[make_pair(V[pos-1][midd].first,V[pos-1][midd].second)];
      }
      if(midd-1>=0)
      {
         if(euk>sqrt((V[pos][end].first-V[pos-1][midd-1].first)*(V[pos][end].first-V[pos-1][midd-1].first)+(V[pos][end].second-V[pos-1][midd-1].second)*(V[pos][end].second-V[pos-1][midd-1].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos-1][midd-1].first)*(V[pos][end].first-V[pos-1][midd-1].first)+(V[pos][end].second-V[pos-1][midd-1].second)*(V[pos][end].second-V[pos-1][midd-1].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos-1][midd-1].first,V[pos-1][midd-1].second)];
         } 
      }
      if(midd-2>=0)
      {
         if(euk>sqrt((V[pos][end].first-V[pos-1][midd-2].first)*(V[pos][end].first-V[pos-1][midd-2].first)+(V[pos][end].second-V[pos-1][midd-2].second)*(V[pos][end].second-V[pos-1][midd-2].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos-1][midd-2].first)*(V[pos][end].first-V[pos-1][midd-2].first)+(V[pos][end].second-V[pos-1][midd-2].second)*(V[pos][end].second-V[pos-1][midd-2].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos-1][midd-2].first,V[pos-1][midd-2].second)];
         } 
      }
      if(midd+1<V[pos-1].size())
      {
         if(euk>sqrt((V[pos][end].first-V[pos-1][midd+1].first)*(V[pos][end].first-V[pos-1][midd+1].first)+(V[pos][end].second-V[pos-1][midd+1].second)*(V[pos][end].second-V[pos-1][midd+1].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos-1][midd+1].first)*(V[pos][end].first-V[pos-1][midd+1].first)+(V[pos][end].second-V[pos-1][midd+1].second)*(V[pos][end].second-V[pos-1][midd+1].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos-1][midd+1].first,V[pos-1][midd+1].second)];
         } 
      }
      if(midd+2<V[pos+1].size())
      {
         if(euk>sqrt((V[pos][end].first-V[pos-1][midd+2].first)*(V[pos][end].first-V[pos-1][midd+2].first)+(V[pos][end].second-V[pos-1][midd+2].second)*(V[pos][end].second-V[pos-1][midd+2].second)))
         {
          euk=sqrt((V[pos][end].first-V[pos-1][midd+2].first)*(V[pos][end].first-V[pos-1][midd+2].first)+(V[pos][end].second-V[pos-1][midd+2].second)*(V[pos][end].second-V[pos-1][midd+2].second));
          toc=mapa[make_pair(V[pos][end].first,V[pos][end].second)];
          toc2=mapa[make_pair(V[pos-1][midd+2].first,V[pos-1][midd+2].second)];
         } 
      }
     }
}  
int main()
{
    scanf("%llu",&a);
    for(ll i=0;i<a;++i)
    {
            scanf("%llu%llu",&b,&c);
            niz[i]=make_pair(b,c);
            mapa[make_pair(b,c)]=i;
    }
    sort(niz,niz+a);

    for(ll i=0;i<a;++i)
    {
            if(mapa2[niz[i].first]==0)
            {
              V[pos1].push_back(make_pair(niz[i].first,niz[i].second));
              mapa2[niz[i].first]=pos1;
              mapa3[pos1]=niz[i].first;
              ++pos1;
            }
            else V[pos1].push_back(make_pair(niz[i].first,niz[i].second));
    }
    for(ll i=0;i<pos1;++i)
    {
            for(ll j=0;j<V[i].size();++j)
            {
                    if(j!=0)
                    {
                       if(euk>V[i][j].second-V[i][j-1].second)
                       {
                          euk=V[i][j].second-V[i][j-1].second;
                          toc=mapa[make_pair(mapa3[i],V[i][j].second)];
                          toc2=mapa[make_pair(V[i][j-1].first,V[i][j-1].second)];
                       }
                    }
                    if(j!=V[i].size()-1)
                    {
                       //prllf("%d\n",V[i][j+1].second-V[i][j].second);
                       if(euk>V[i][j+1].second-V[i][j].second)
                       {
                          euk=V[i][j+1].second-V[i][j].second;
                          toc=mapa[make_pair(mapa3[i],V[i][j].second)];
                          toc2=mapa[make_pair(V[i][j+1].first,V[i][j+1].second)];
                       }
                    }
                    binary(i,j);
            }
    }
    printf("%llu %llu %.6lf\n",min(toc,toc2),max(toc,toc2),euk+ + 1e-9);
}

1 个答案:

答案 0 :(得分:1)

我无法告诉你你的错误是什么,但我会告诉你如何找到它。为少量点编写蛮力解决方案非常简单 - 只需计算任意两对之间的距离并找到这些距离的最小值。对于小n,这个解决方案足够好了。现在生成具有相对较小坐标(比如最多100个)的随机点(比如最多20个)并比较解决方案和蛮力的答案。继续这样做,直到你的解决方案和蛮力的答案不同为止。当我尝试这种方法时,我发现我错误的情况非常快,第一时间我在20秒内找不到错误的测试,结果证明我已经修复了我的解决方案。

我在一周前解决了一个非常类似的问题,我能够用我描述的方法修复我的解决方案。我也是在竞选期间做到了这一点,我相信这是解决可能存在许多优势问题的正确方法。

顺便说一句,这个问题的经典解决方案是使用divide and conquer,这就是我实现的方法。

编辑:实际上经过一番思考后,我想我可以举例说明你的解决方案失败了。你的逻辑是错误的 - 可能是你需要倒数第二个(甚至更远)的情况。试试这一点:(1, 1), (2,100), (3,2)