HDU 1007 Quoit Design

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007

题目大概没怎么读懂= =。。但是题意抽象出来的话就是求n个点中最短距离的两个点为直径的圆的半径。

因为n最大可取10^5,所以O(n^2)的暴力算法肯定是无法通过的,所以选择采用分治的O(nlogn)的算法。然后。。貌似就没什么然后了,只剩下模版的练习了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MIN(a,b) ((a<b)?(a):(b))
int n,a[100010];
struct point{
    double x,y;
}points[100010];
bool cmpx(point a,point b){
    if(a.x<b.x) return true;
    return false;
}
bool cmpy(int a,int b){
    if(points[a].y<points[b].y) return true;
    return false;
}
double dis(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double min(double a,double b)
{
  return a<b?a:b;
}
double mindis(int l,int r){
    if(l+1==r)
        return dis(points[l],points[r]);
    if(l+2==r)
        return min(dis(points[l],points[r]),min(dis(points[l],points[l+1]),dis(points[l+1],points[r])));
    int mid=(l+r)>>1;
    double ans;
    ans=min(mindis(l,mid),mindis(mid+1,r));
    int count=0;
    for(int i=l;i<=r;i++){
        if(fabs(points[mid].x-points[i].x)<=ans)
            a[count++]=i;
    }
    sort(a,a+count,cmpy);
    for(int i=0;i<count;i++){
        for(int j=i+1;j<count;j++){
            if(points[a[j]].y-points[a[i]].y>ans)  break;
            ans=min(ans,dis(points[a[i]],points[a[j]]));
        }
    }
    return ans;
}
int main(){
    while(~scanf("%d",&n)&&n){
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&points[i].x,&points[i].y);
        sort(points,points+n,cmpx);
        double ans=0.5*mindis(0,n-1);
        printf("%.2lf\n",ans);
    }
    return 0;
}


posted @ 2014-05-18 23:34  gaoxiang36999  阅读(233)  评论(0)    收藏  举报