最近一对SPOJ logN时间回答错误

Closest pair SPOJ logN time wrong answer

本文关键字:错误 时间 logN SPOJ 最近      更新时间:2023-10-16

我正在努力解决这个问题。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 %dn",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("%dn",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 %.6lfn",min(toc,toc2),max(toc,toc2),euk+ + 1e-9);
}

我不能告诉你你的错误是什么,但我会告诉你如何找到它。为少量点编写强力解决方案非常容易,只需计算任意两对之间的距离并找到这些距离中的最小值。对于小n,这个解就足够了。现在用相对较小的坐标(比如最多100)生成随机点(比如最多20个),并比较你的解决方案和蛮力的答案。继续这样做,直到你的解决方案和蛮力的答案不同。当我尝试这种方法时,我很快就发现了我出错的情况,当我在20秒内第一次找不到错误的测试时,我发现我已经解决了问题。

大约一周前,我解决了一个非常类似的问题,我能够用我描述的方法来解决我的问题。此外,我在一次跑步比赛中也这样做过,我相信这是解决可能存在许多边缘情况的问题的正确方法。

顺便说一句,这个问题的经典解决方案是使用分而治之,这就是我实现的方法。

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