hdu 1007分治


标题:最近点対を求める
暴力は必ずタイムアウトし、分治する:(コードは他の人を参考にする)
最大のリングを求めて、このリングは1つしかカバーできないので、まず距離の最小の2点を見つけることができて、その距離はリングの直径で、さもなくばこのリングは1回に2つのリングをカバーすることができます.だからこの問題の意味は:最近の点を求めて正しいです.
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#define DX(x) ((x)*(x))
using namespace std;
const int MAX=100000+1;
int n;
struct Point
{
    double x,y;
    int index;
}a[MAX],b[MAX],c[MAX];
double getdis(Point a,Point b)
{
       return sqrt(DX(a.x-b.x)+DX(a.y-b.y));
}
/*double getmin(double a,double b)
{
       if(a<b) return a;
       else return b;
}*/
inline double getmin(double a, double b)
 {
     return a < b ? a : b;
 }
bool cmpx(const Point& a,const Point& b)
{
     if(a.x==b.x) return a.y<b.y;
     return a.x<b.x;
}
bool cmpy(const Point& a,const Point& b)
{
     if(a.y==b.y) return a.x<b.x;
     return a.y<b.y;
}
void merget(Point b[],Point c[],int p,int m,int q)   //   
{
     int i,j,k;
     for(i=p,k=p,j=m+1;i<=m&&j<=q;)   //     y      ,      
                                      //       y ,     y      
     {
          if(c[i].y>c[k].y)  b[k++]=c[i], j++;
          else  b[k++]=c[i],i++;
     }
     while(i<=m)  b[k++]=c[i++];
     while(j<=q)  b[k++]=c[j++];
}
double closet(Point a[],Point b[],Point c[],int p,int q)
{
       double d1,d2;
       if(q - p == 1) return getdis(a[p],a[q]);
       if(q - p == 2)
       {
            double x1=getdis(a[p],a[p+1]);
            double x2=getdis(a[p],a[q]);
            double x3=getdis(a[p+1],a[q]);
            return getmin(x1,getmin(x2,x3));
       }
       
           int m=(q + p)/2,i,j,k;
           //        、
           for(i = p,j = p,k = m + 1; i <=q; ++i)
           {
                if(b[i].index<=m) c[j++]=b[i];
                else c[k++]=b[i];
           } 
           d1=closet(a,c,b,p,m);
           d2=closet(a,c,b,m+1,q);
           merget(b,c,p,m,q);
           double dm=getmin(d1,d2);
           for(i = p, k = p;i <= q;++i)
           {
               if(fabs(b[i].x-b[m].x) < dm)
                    c[k++]=b[i];
           }
           for(i = p; i < k; ++i)
           {
                 for(j = i + 1; j < k && c[j].y - c[i].y < dm; ++j)
                 {
                      double temp=getdis(c[i],c[j]);
                      if(temp < dm) dm=temp;
                 } 
           }
           return dm;
}
int main()
{
    
    while(scanf("%d",&n)!=EOF&&n!=0)
    {
         for(int i=0;i<n;i++)   
         {scanf("%lf%lf",&a[i].x,&a[i].y); }
         sort(a,a+n,cmpx);
         for(int i=0;i<n;i++)  a[i].index=i;
         memcpy(b,a,n*sizeof(b[0]));
         sort(b,b+n,cmpy);
         double dis=closet(a,b,c,0,n-1);
         printf("%.2lf
",dis/2.0);          }     return 0; }

注1: