hdu 1007 Quoit Design (分治+遞迴)
阿新 • • 發佈:2018-11-11
題意就是輸入一堆點在二維平面上的座標,找出距離最短的兩個點對,距離除以2輸出。
很簡單的遞迴加分治。然而我昨天寫的時候WA到心態爆炸,今天終於明白整個結構都有問題,重新修改了一遍,直接過了。
附上程式碼:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iterator>
using namespace std ;
const int inf=0x7fffffff;
const int maxn=100000;
vector<pair<double ,double> >vis;
int n;
double minz;
double minl;
double minr;
int tmp[maxn];
bool cmp(pair<double ,double >a,pair<double ,double > b)
{
if(a.first==b.first)return a.second<b.second;
return a.first<b.first;
}
double cal(pair<double ,double >a,pair<double ,double >b)
{
double x=fabs(a.first-b.first);
double y=fabs(a.second-b.second);
return sqrt(x*x+y*y);
}
double min(double l1,double l2)
{
return l1>l2?l2:l1;
}
bool cmp1(int a,int b)
{
return vis[a].second<vis[b].second;
}
double find(int left ,int right)
{
if(left==right)return inf;
double d=inf;
if(left+1==right)
{
return cal(vis[left],vis[right]);
}
int mid=(left+right)>>1;
double l1=find(left,mid);
double l2=find(mid+1,right);
d=min(l1,l2);
int k=0;
for(int i=left;i<=right;i++)
{
if(fabs(vis[mid].first-vis[i].first)<d)
{
tmp[k++]=i;
}
}
sort(tmp,tmp+k,cmp1);
for(int i=0;i<k;i++)
{
for(int j=i+1;j<k;j++)
{
if(vis[tmp[j]].second-vis[tmp[i]].second>=d)break;
d=min(d,cal(vis[tmp[j]],vis[tmp[i]]));
}
}
return d;
}
int main()
{
while(scanf("%d",&n))
{
vis.clear();
minz=inf;
minl=inf;
minr=inf;
if(n==0)break;
for(int i=0;i<n;i++)
{
double a,b;
scanf("%lf%lf",&a,&b);
vis.push_back(make_pair(a,b));
}
if(n<=2)
{
if(n==2)minz=cal(vis[0],vis[1]);
else if(n==1)minz=0;
printf("%.2lf\n",minz/2);
continue;
}
else
{
sort(vis.begin(),vis.end(),cmp);
minz=find(0,n-1);
printf("%.2lf\n",minz/2);
}
}
}