1. 程式人生 > >hdu 1007 Quoit Design (分治+遞迴)

hdu 1007 Quoit Design (分治+遞迴)

題意就是輸入一堆點在二維平面上的座標,找出距離最短的兩個點對,距離除以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); } } }