hdu 1007 Quoit Design

        阅读了一下平面最近点对的姿势,直接找了一道裸题来做。看完姿势的时候,我一直想不通合并时要怎么实现只考察最近6个点。。其实看了一下其他人的代码,好像都没有写只考察6个点。另外,每次合并,都要进行一次排序,那么它的真正复杂度是不是nlognlogn呢。。不管怎么样,比暴力快了许多。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
#include <stack>

using namespace std;

const int mod=1e9+7;

#define type double
#define Vector Point
const double PI = 3.14159265358979323;

//二维点/二维向量
struct Point{
    type x,y;
    Point(){
    }
    Point(type x,type y):x(x),y(y){
    }
    Point operator-(Point other){
        return Point(x-other.x,y-other.y);
    }
};

//向量长度
double Length(Vector a){
    return sqrt(a.x*a.x+a.y*a.y+0.0);
}



Point pts[100010];

bool byx(const Point& a,const Point& b){
    return a.x<b.x;
}

bool byy(const Point& a,const Point& b){
    return a.y<b.y;
}

Point tmp[100010];

//最近点对
type Nearest(Point* pts,int l,int r){
	if(r-l==2){
		return Length(pts[l+1]-pts[l]);
	}
	if(r-l==3){
		double re=min(Length(pts[l+1]-pts[l]),Length(pts[l+2]-pts[l]));
		re=min(re,Length(pts[l+2]-pts[l+1]));
		return re;
	}
    int mid = (l+r)>>1;
    type Minl=Nearest(pts,l,mid);
    type Minr=Nearest(pts,mid,r);
    type re = min(Minl,Minr);
    int cnt=0;
    int pos;
    //tmp暂存分割线附近的点
    pos=mid-1;
    while(1){
        if(pos<l)break;
        if(pts[pos].x>pts[mid].x-re){
            tmp[cnt++]=pts[pos];
            pos--;
        }else{
            break;
        }
    }
    pos=mid;
    while(1){
        if(pos>=r)break;
        if(pts[pos].x<pts[mid].x+re){
            tmp[cnt++]=pts[pos];
            pos++;
        }else{
            break;
        }
    }
    //感觉有点耍流氓,能不能不排序
    sort(tmp,tmp+cnt,byy);  //通过y排序

    for(int i=0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(tmp[j].y-tmp[i].y>re)break;
            re=min(re,Length(tmp[j]-tmp[i]));
        }
    }
    return re;
}

int main(){
	int n;
	while(cin>>n){
        if(n==0)break;
        for(int i=0;i<n;i++){
            scanf("%lf%lf",&pts[i].x,&pts[i].y);

        }
        sort(pts,pts+n,byx);
        double ans = Nearest(pts,0,n);
        printf("%.2f\n",ans/2);
	}
	return 0;
}

你可能感兴趣的:(hdu 1007 Quoit Design)