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;
}

浙公网安备 33010602011771号