HDU 1007 Quoit Design

来源:互联网 发布:南京万博软件科技 编辑:程序博客网 时间:2024/05/29 18:34

题目链接: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;}


0 0
原创粉丝点击