hdu1007
http://acm.hdu.edu.cn/showproblem.php?pid=1007
解题关键:分治算法求解,注意学习分治算法的写法
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 #define inf 0x3f3f3f3f 8 using namespace std; 9 typedef long long ll; 10 struct point{ 11 double x,y; 12 }p[100002],tmp[100002]; 13 double dis(point &a,point &b){ 14 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 15 } 16 bool cmp1(point &a,point &b){ 17 return a.x<b.x; 18 } 19 bool cmp2(point &a,point &b){ 20 return a.y<b.y; 21 } 22 double closet(int l,int r){ 23 if(l==r) return inf; 24 if(l+1==r) return dis(p[l],p[r]); 25 int mid=(l+r)>>1; 26 double d1,d2,d; 27 d1=closet(l, mid),d2=closet(mid+1, r); 28 d=min(d1,d2); 29 int k=0; 30 for(int i=l;i<=r;i++){ 31 if(fabs(p[i].x-p[mid].x)<mid) tmp[k++]=p[i]; 32 } 33 sort(tmp, tmp+k,cmp2); 34 for(int i=0;i<k-1;i++){ 35 for(int j=i+1;j<k;j++){ 36 if(fabs(tmp[j].y-tmp[i].y)>=d) break; 37 d=min(d,dis(tmp[i],tmp[j])); 38 } 39 } 40 return d; 41 } 42 43 44 int main(){ 45 int n; 46 while(scanf("%d",&n)!=EOF){ 47 if(!n) continue; 48 for(int i=0;i<n;i++){ 49 scanf("%lf%lf",&p[i].x,&p[i].y); 50 } 51 sort(p,p+n,cmp1); 52 double ans=closet(0, n-1); 53 printf("%.2f ",ans/2); 54 } 55 56 }
树上分治和数列分治待补。