我正在努力解决这个问题。 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);
}
答案 0 :(得分:1)
我无法告诉你你的错误是什么,但我会告诉你如何找到它。为少量点编写蛮力解决方案非常简单 - 只需计算任意两对之间的距离并找到这些距离的最小值。对于小n,这个解决方案足够好了。现在生成具有相对较小坐标(比如最多100个)的随机点(比如最多20个)并比较解决方案和蛮力的答案。继续这样做,直到你的解决方案和蛮力的答案不同为止。当我尝试这种方法时,我发现我错误的情况非常快,第一时间我在20秒内找不到错误的测试,结果证明我已经修复了我的解决方案。
我在一周前解决了一个非常类似的问题,我能够用我描述的方法修复我的解决方案。我也是在竞选期间做到了这一点,我相信这是解决可能存在许多优势问题的正确方法。
顺便说一句,这个问题的经典解决方案是使用divide and conquer,这就是我实现的方法。
编辑:实际上经过一番思考后,我想我可以举例说明你的解决方案失败了。你的逻辑是错误的 - 可能是你需要倒数第二个(甚至更远)的情况。试试这一点:(1, 1), (2,100), (3,2)