• HDU1007:Quoit Design——题解


    http://acm.hdu.edu.cn/showproblem.php?pid=1007

    题目大意:给n个点,求点对最短距离/2.

    ——————————————————————

    平面分治裸题。

    暂时还不想讲为什么这么做。

    所以原理暂割。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    const dl INF=1e20;
    const int N=100001;
    struct node{
        dl x;
        dl y;
    }p[N],a[N],b[N],c[N];
    bool cmp(node A,node B){
        return A.x<B.x;
    }
    inline dl dis(int i,int j){
        return sqrt(pow(b[i].x-c[j].x,2)+pow(b[i].y-c[j].y,2));
    }
    dl solve(int l,int r){
        if(l>=r)return INF;
        int mid=(l+r)>>1;
        dl x0=(p[mid].x+p[mid+1].x)/2.0;
        dl d=min(solve(l,mid),solve(mid+1,r));
        int l1=l,r1=mid+1,bnum=0,cnum=0;
        for(int i=l;i<=r;i++){
        if(l1<=mid&&(r1>r||p[l1].y<p[r1].y)){
            a[i]=p[l1++];
            if(x0-d<a[i].x)b[++bnum]=a[i];
        }else{
            a[i]=p[r1++];
            if(a[i].x<x0+d)c[++cnum]=a[i];
        }
        }
        for(int i=l;i<=r;i++)p[i]=a[i];
    
        for(int i=1,j=1;i<=bnum||j<=cnum;){
        if(i<=bnum&&(j>cnum||b[i].y<c[j].y)){
            for(int k=j-1;k>=1;k--){
            if(b[i].y-d>=c[k].y)break;
            d=min(d,dis(i,k));
            }
            i++;
        }else{
            for(int k=i-1;k>=1;k--){
            if(c[j].y-d>=b[k].y)break;
            d=min(d,dis(k,j));
            }
            j++;
        }
        }
        return d;
    }
    int main(){
        int n;
        while(scanf("%d",&n)!=EOF&&n){
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        sort(p+1,p+n+1,cmp);
        printf("%.2f
    ",solve(1,n)/2.0);
        }
        return 0;
    }
  • 相关阅读:
    随笔
    随笔
    第一个存储过程
    mysql 存储过程
    join
    随笔
    玩家注册登录
    mysql 存储二进制数据
    mysql学习
    socket listen/accept
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8032189.html
Copyright © 2020-2023  润新知