zoukankan      html  css  js  c++  java
  • HDU 1007 Quoit Design最近点对( 分治法)

    题意:

      给出平面上的n个点,问任意点对之间的最短距离是多少? 

    思路:

      先将所有点按照x坐标排序,用二分法将n个点一分为二个部分,递归下去直到剩下两或一个点。对于一个部分,左右部分的答案分别都知道,那么可能的答案就是min(left_ans,right_ans) 。注意更小的点对可能一个在左,一个在右。所以还得处理两个边内的紧靠着的部分,如果左边的一个点到达中线的距离已经超过当前最短距离,那么这个点到达右边任意一个点也不会是最短距离了。同时,若一左一右的两个点的y距离已经超过目前最短距离,那么也不可能是最短距离,可能为答案的点对并不太多,大概O(n)对。因此,还得在x距离满足的情况下,y也得满足,所以y也得排序。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 struct node
     5 { 
     6     double x,y;
     7 }a[100005];  
     8 
     9 int c[100005];  
    10 
    11 double cmpy(int t1,int t2) { return a[t1].y<a[t2].y;}
    12 bool cmp(node t1,node t2) { return t1.x<t2.x; }  
    13 double dis(node t1,node t2) {return sqrt((t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y));}  
    14 
    15 double find(int left,int right)  
    16 {  
    17     if(left+1==right)    return dis(a[left],a[right]);  
    18     if(left==right)        return 2147483.999;  
    19 
    20     int mid=(left+right)>>1;
    21     double aa=find(left,mid);
    22     double bb=find(mid+1,right);
    23     double ans=min(aa,bb); //当前最小
    24 
    25     int cnt=0;
    26     double x=a[mid].x;
    27     for(int i=left; i<=right; i++)
    28         if(fabs(a[i].x-x)<ans)    c[cnt++]=i;
    29     sort(c,c+cnt,cmpy);        //按y来排序
    30 
    31 
    32     for(int i=0;i<cnt;i++)        //计算x=[mid-ans,mid+ans]
    33         for(int j=i+1;j<cnt;j++)    
    34         {    
    35             if(a[c[j]].y-a[c[i]].y>ans)    break; //两点的距离已超过ans
    36             ans=min(ans,dis(a[c[i]],a[c[j]]));    //求最小距离
    37         }   
    38     return ans;
    39 }  
    40 
    41 int main()  
    42 {  
    43     int n,i;  
    44     while(cin>>n,n)  
    45     {  
    46         for(i=0;i<n;i++)     
    47             scanf("%lf%lf",&a[i].x,&a[i].y);
    48         sort(a,a+n,cmp);      //按X排序
    49         printf("%.2lf
    ",find(0,n-1)/2);
    50     }  
    51     return 0;  
    52 }
    AC代码
  • 相关阅读:
    linux 常用命令
    基于 DirectX11 的 MMDViewer 01-简介
    基于 DirectX11 的 MMDViewer 04-渲染目标视图和多视口
    基于 DirectX11 的 MMDViewer 03-渲染管线
    基于 DirectX11 的 MMDViewer 02-创建一个窗口
    Simple2D-26 Simple2D 最后的工作,开发结束
    Simple2D-25 精灵动作
    Simple2D-24 Sprite 渲染树
    Simple2D-23(重构)反走样几何图形
    Simple2D-22(重构)纹理池
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4881625.html
Copyright © 2011-2022 走看看