第一個專題基礎演算法分治hdu 1007
阿新 • • 發佈:2019-01-06
//1.只有一個點,那就是無窮 //2.只有兩個點,那就是這兩點間距離 //3.其它情況 ,左邊,右邊,跨中間(先小範圍比較x,然後在這一小範圍排序縱座標,更新最近值) #include <iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; struct grou{ double x; double y; }group[100004],temp[100004]; double cmp(grou a,grou b) { return a.x<b.x; } double comp(grou m,grou n) { return m.y<n.y; } double dist(grou a,grou b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double closest(int l,int r)//下標l到r的最短距離 { double dis=0x3ffffff; if(l==r) return dis; if(l+1==r) return dist(group[l],group[r]); int mid=(l+r)/2; double d1=closest(l,mid); double d2=closest(mid+1,r); dis=min(d1,d2); int k=0; //接下來處理在mid附近最小範圍的點,也就是距離比dis小,先比較橫座標,然後是縱座標 for(int i=l;i<r;i++) { if(fabs(group[i].x-group[mid].x)<=dis) temp[k++]=group[i]; } //接下來排序縱座標 sort(temp,temp+k,comp); //接下來列舉更新closest的值 for(int i=0;i<k;i++) { for(int j=i+1;j<k&&temp[j].y-temp[i].y<dis;j++)//這樣寫TLEl { dis=min(dis,dist(temp[i],temp[j])); } } return dis; } int main() { int n; while(~scanf("%d",&n)&&n) { for(int i=0;i<n;i++) { scanf("%lf%lf",&group[i].x,&group[i].y); } sort(group,group+n,cmp); printf("%.2f\n",closest(0,n-1)/2);//最短距離的一半 } return 0; }