hdu1007 Quoit Design

第一次做计算几何,看了算法导论的算法,再看了网上的一些代码,发现很多实际上并没有完整地实现分治法,然后试图自己实现

失败告终T_T

于是有了如下代码,分治法的思想详见算法导论与编程之美

耗时是1250ms

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#define MAX 100010
struct point
{
    double x;
    double y;
};
double D_MAX=99999999999;  
point X[MAX];
point Y[MAX];
double cal(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int cmp1(const void *a,const void *b)
{
    if((*(point *)a).x==(*(point *)b).x)
    {
        return 0;
    }
    return ((*(point *)a).x-(*(point *)b).x)>0?1:(-1);
}
int cmp2(const void *a,const void *b)
{
    if((*(point *)a).y==(*(point *)b).y)
    {
        return 0;
    }
    return ((*(point *)a).y-(*(point *)b).y)>0?1:(-1);
}
double fin(int l,int r)
{
    int i,j;
    if(l==r)
    {
        return D_MAX;
    }
    if(l==r-1)
    {
        return cal(X[l],X[r]);
    }
    double res;
    if(l==r-2)
    {
        double d[3];
        d[0]=cal(X[l],X[l+1]);
        d[1]=cal(X[l+1],X[l+2]);
        d[2]=cal(X[l],X[r]);
        res=d[0];
        res=res>d[1]?d[1]:res;
        res=res>d[2]?d[2]:res;
        return res;
    }
    int mid=(l+r)>>1;
    double left=fin(l,mid);
    double right=fin(mid+1,r);
    double best=left>right?right:left;
    int k=0;
    for(i=l;i<=r&&abs(X[i].x-X[mid].x)<best;i++)
    {
        Y[k++]=X[i];
    }
    qsort(Y,k,sizeof(Y[0]),cmp2);
    for(i=0;i<k;i++)
    {
        for(j=i+1;j<k;j++)
        {
            if(Y[j].y-Y[i].y>best)
            {
                break;
            }
            double temp=cal(Y[i],Y[j]);
            if(temp<best)
            {
                best=temp;
            }
        }
    }
    return best;
}
void main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        int i;
        for(i=0;i<n;i++)
        {
            scanf("%lf %lf",&X[i].x,&X[i].y);
        }
        qsort(X,n,sizeof(X[0]),cmp1);
        double res=fin(0,n-1);
        printf("%.2lf\n",res/2);
    }
}

posted @ 2012-07-14 11:12  willzhang  阅读(188)  评论(0编辑  收藏  举报