#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define hhh puts("hhh")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+7;
const double eps = 1e-9;
int sgn(double d) {
if(fabs(d)<eps) return 0;
if(d>0) return 1;
return -1;
}
int dcmp(double x, double y=0) {
if(fabs(x-y)<eps) return 0;
if(x>y) return 1;
return -1;
}
struct Point{
double x, y;
Point(double x=0, double y=0):x(x), y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B) {return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Point A, Point B) {return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A, double p) {return Vector(A.x*p,A.y*p);}
Vector operator / (Vector A, double p) {return Vector(A.x/p,A.y/p);}
bool operator < (const Point &a, const Point &b) {
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
bool operator == (const Point &a, const Point &b) {
if(sgn(a.x-b.x)==0 && sgn(a.y-b.y)==0) return true;
return false;
}
double Dot(Vector A, Vector B) {
return A.x*B.x+A.y*B.y;
}
double Cross(Vector A, Vector B) {
return A.x*B.y-A.y*B.x;
}
double Length(Vector A) {
return sqrt(Dot(A,A));
}
double Angle(Vector A, Vector B) {
return acos(Dot(A,B)/Length(A)/Length(B));
}
double Area2(Point A, Point B, Point C) {
return Cross(B-A,C-A);
}
Vector Rotate(Vector A, double rad) {
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A) {
double L=Length(A);
return Vector(-A.y/L,A.x/L);
}
bool ToLeftTest(Point a, Point b, Point c) {
return Cross(b-a,c-b)>0;
}
struct Line{
Point v, p;
Line(){}
Line(Point v, Point p):v(v), p(p) {}
Point point(double t) {
return v+(p-v)*t;
}
};
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
Vector u=P-Q;
double t=Cross(w,u)/Cross(v,w);
return P+v*t;
}
double DistanceToLine(Point P, Point A, Point B) {
Vector v1=B-A, v2=P-A;
return fabs(Cross(v1,v2)/Length(v1));
}
double DistanceToSegment(Point P, Point A, Point B) {
if(A==B) return Length(P-A);
Vector v1=B-A, v2=P-A, v3=P-B;
if(dcmp(Dot(v1,v2))<0) return Length(v2);
if(dcmp(Dot(v1,v3))>0) return Length(v3);
return DistanceToLine(P,A,B);
}
Point GetLineProjection(Point P, Point A, Point B) {
Vector v=B-A;
return A+v*(Dot(v,P-A)/Dot(v,v));
}
bool OnSegment(Point p, Point a1, Point a2) {
return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dot(a1-p,a2-p))<=0;
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
double c1=Cross(a2-a1,b1-a1), c2=Cross(a2-a1,b2-a1);
double c3=Cross(b2-b1,a1-b1), c4=Cross(b2-b1,a2-b1);
if(!sgn(c1)||!sgn(c2)||!sgn(c3)||!sgn(c4)) {
bool f1=OnSegment(b1,a1,a2);
bool f2=OnSegment(b2,a1,a2);
bool f3=OnSegment(a1,b1,b2);
bool f4=OnSegment(a2,b1,b2);
bool f=(f1|f2|f3|f4);
return f;
}
return sgn(c1)*sgn(c2)<0 && sgn(c3)*sgn(c4)<0;
}
double PolygonArea(Point *p, int n) {
double s=0;
for(int i=1; i<n-1; ++i) s+=Cross(p[i]-p[0],p[i+1]-p[0]);
return s/2;
}
int isPointInPolygon(Point p, vector<Point> poly) {
int wn=0;
int n=poly.size();
for(int i=0; i<n; ++i) {
if(OnSegment(p,poly[i],poly[(i+1)%n])) return -1;
int k=sgn(Cross(poly[(i+1)%n]-poly[i],p-poly[i]));
int d1=sgn(poly[i].y-p.y);
int d2=sgn(poly[(i+1)%n].y-p.y);
if(k>0&&d1<=0&&d2>0) wn++;
if(k<0&&d2<=0&&d1>0) wn--;
}
if(wn!=0) return 1;
return 0;
}
struct Circle{
Point c;
double r;
Circle(Point c, double r):c(c), r(r) {}
Point point(double a) {
return Point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
int getLineCircleIntersection(Line L, Circle C, double &t1, double &t2, vector<Point> &sol) {
double a=L.v.x, b=L.p.x-C.c.x, c=L.v.y, d=L.p.y-C.c.y;
double e=a*a+c*c, f=2*(a*b+c*d), g=b*b+d*d-C.r*C.r;
double delta=f*f-4*e*g;
if(sgn(delta)<0) return 0;
if(sgn(delta)==0) {
t1=-f/(2*e);
t2=-f/(2*e);
sol.push_back(L.point(t1));
return 1;
}
t1=(-f-sqrt(delta))/(2*e);
sol.push_back(L.point(t1));
t2=(-f+sqrt(delta))/(2*e);
sol.push_back(L.point(t2));
return 2;
}
double AreaOfOverlap(Point c1, double r1, Point c2, double r2) {
double d=Length(c1-c2);
if(r1+r2<d+eps) return 0.0;
if(d<fabs(r1-r2)+eps) {
double r=min(r1,r2);
return acos(-1)*r*r;
}
double x=(d*d+r1*r1-r2*r2)/(2.0*d);
double p=(r1+r2+d)/2.0;
double t1=acos(x/r1);
double t2=acos((d-x)/r2);
double s1=r1*r1*t1;
double s2=r2*r2*t2;
double s3=2*sqrt(p*(p-r1)*(p-r2)*(p-d));
return s1+s2-s3;
}
Point lst[maxn];
int stk[maxn], top;
bool cmp(Point p1, Point p2) {
int tmp=sgn(Cross(p1-lst[0],p2-lst[0]));
if(tmp>0) return true;
if(tmp==0&&Length(lst[0]-p1)<Length(lst[0]-p2)) return true;
return false;
}
void Graham(int n) {
int k=0;
Point p0;
p0.x=lst[0].x;
p0.y=lst[0].y;
for(int i=1; i<n; ++i) {
if(p0.y>lst[i].y || (p0.y==lst[i].y&&p0.x>lst[i].x)) {
p0.x=lst[i].x;
p0.y=lst[i].y;
k=i;
}
}
lst[k]=lst[0];
lst[0]=p0;
sort(lst+1,lst+n,cmp);
if(n==1) { top=1; stk[0]=0; return; }
if(n==2) { top=2; stk[0]=0; stk[1]=1; return; }
stk[0]=0, stk[1]=1, top=2;
for(int i=2; i<n; ++i) {
while(top>1&&Cross(lst[stk[top-1]]-lst[stk[top-2]],lst[i]-lst[stk[top-2]])<=0) --top;
stk[top]=i, ++top;
}
}
double sqr(double x){
return x*x;
}
double dis(Point a,Point b){
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
Point Incenter(Point a,Point b,Point c){
double A=dis(b,c);
double B=dis(a,c);
double C=dis(a,b);
double S=A+B+C;
double x=(A*a.x+B*b.x+C*c.x)/S;
double y=(A*a.y+B*b.y+C*c.y)/S;
return Point(x,y);
}
Point gravity(Point a,Point b,Point c){
double x=(a.x+b.x+c.x)/3;
double y=(a.y+b.y+c.y)/3;
return Point(x,y);
}
Point Circum(Point a,Point b,Point c){
double x1=a.x,y1=a.y;
double x2=b.x,y2=b.y;
double x3=c.x,y3=c.y;
double a1=2*(x2-x1);
double b1=2*(y2-y1);
double c1=x2*x2+y2*y2-x1*x1-y1*y1;
double a2=2*(x3-x2);
double b2=2*(y3-y2);
double c2=x3*x3+y3*y3-x2*x2-y2*y2;
double x=(c1*b2-c2*b1)/(a1*b2-a2*b1);
double y=(a1*c2-a2*c1)/(a1*b2-a2*b1);
return Point(x,y);
}
Point ortho(Point a,Point b,Point c){
double A1=b.x-c.x;
double B1=b.y-c.y;
double C1=A1*a.y-B1*a.x;
double A2=a.x-c.x;
double B2=a.y-c.y;
double C2=A2*b.y-B2*b.x;
double x=(A1*C2-A2*C1)/(A2*B1-A1*B2);
double y=(B1*C2-B2*C1)/(A2*B1-A1*B2);
return Point(x,y);
}
double crossProduct(double x1, double y1, double x2, double y2) {
return x1 * y2 - x2 * y1;
}
bool isInside(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3) {
if (crossProduct(x3 - x1, y3 - y1, x2 - x1, y2 - y1) == 0) {
return false;
}
if(crossProduct(x3 - x1, y3 - y1, x2 - x1, y2 - y1) >= 0)
{
double tmpx = x2;
double tmpy = y2;
x2 = x3;
y2 = y3;
x3 = tmpx;
y3 = tmpy;
}
if(crossProduct(x2 - x1, y2 - y1, x - x1, y - y1) < 0) return false;
if(crossProduct(x3 - x2, y3 - y2, x - x2, y - y2) < 0) return false;
if(crossProduct(x1 - x3, y1 - y3, x - x3, y - y3) < 0) return false;
return true;
}
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=1e5+5;
struct Point{
double x,y;
}p[MAXN];
int temp[MAXN];
bool cmpx(const Point &a,const Point &b){
return a.x<b.x;
}
bool cmpy(const int &a,const int &b){
return p[a].y<p[b].y;
}
double dis(int a,int b){
return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}
double min(double a,double b){
return a<b?a:b;
}
double closestPair(int l,int r)
{
if(r==l) return (1<<30);
if(r-l==1) return dis(l,r);
int mid=(r+l)>>1;
double d1=closestPair(l,mid);
double d2=closestPair(mid+1,r);
double d=min(d1,d2);
int cnt=0;
for(int i=l;i<=r;i++)
if(fabs(p[i].x-p[mid].x)<d) temp[cnt++]=i;
sort(temp,temp+cnt,cmpy);
for(int i=0;i<cnt;i++)
for(int j=i+1;j<=i+6 && j<cnt;j++){
if(p[temp[j]].y-p[temp[i]].y>=d) break;
d=min(d,dis(temp[i],temp[j]));
}
return d;
}
int main(){
int n;
while(scanf("%d",&n),n){
for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p,p+n,cmpx);
printf("%.2f\n",closestPair(0,n-1)/2);
}
return 0;
}
double arc(double x0, double y0, double x1, double y1, double x2, double y2) {
double r,ab,k,b,h,so,C,l,O,s;
r=sqrt((x1-x0)*(x1-x0)+(y1-y0)*(y1-y0));
double r2=(x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);
ab=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
double ab2=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
double co=(2*r2-ab2)/(2*r2);
O=acos(co);
if(fabs(ab-2*r)<eps)
{
l=PI*r;
return l;
}
else
{
if(O>PI)
O=2*PI-O;
l=O*r;
return l;
}
}
详细介绍请看:(20条消息) 计算几何基础【用图来助你理解几何算法】_星空皓月的博客-CSDN博客
(23条消息) 计算几何基础【用图来助你理解几何算法】_星空皓月的博客-CSDN博客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】