hdu 1007(最小点对)

题目链接:点击打开链接

分析:本题就是求解给出的点的最小点对。
代码如下:

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <utility>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;
const double pi=acos(-1);
const int maxn=100005;
const int INF=0x3f3f3f;
struct Point{
    double x,y;
}p[maxn],a[maxn],b[maxn];
bool cmpx(Point a,Point b){
    return a.x<b.x;
}
bool cmpy(Point a,Point b){
    return a.y<b.y;
}
double Cross(Point a,Point b,Point c){
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
double dot(Point a,Point b,Point c){
    return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}
double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
Point cals(Point a,Point b,double r){
    Point ans;
    ans.x=(a.x-b.x)*cos(r)-(a.y-b.y)*sin(r)+b.x;
    ans.y=(a.x-b.x)*sin(r)+(a.y-b.y)*cos(r)+b.y;
    return ans;
}//旋转
double solve(int s,int e){
    if(s+1==e)return dis(a[s],a[e]);
    if(s+2==e)return min(dis(a[s],a[s+1]),min(dis(a[s+1],a[e]),dis(a[s],a[e])));
    int mid=(s+e)>>1;
    double ans=min(solve(s,mid),solve(mid+1,e));
    int cnt=0;
    for(int i=s;i<=e;i++){
        if(a[i].x>=a[mid].x-ans&&a[i].x<=a[mid].x+ans)
        b[cnt++]=a[i];
    }
    sort(b,b+cnt,cmpy);
    for(int i=0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(b[j].y-b[i].y>=ans)
            break;
            ans=min(ans,dis(b[j],b[i]));
        }
    }
    return  ans;
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF&&n){
        for(int i=0;i<n;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
            a[i]=p[i];
        }
        sort(a,a+n,cmpx);
        printf("%.2f\n",solve(0,n-1)/2);
    }
    return 0;
}


你可能感兴趣的:(计算几何)