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

        最近点对一般想到枚举  ,一一枚举时间复杂度为n^2;枚举时候一些操作是多余的,有了分治算法的思想 ,把一些问题分个击破,再回到整体。


    题目链接


      以这道题为例,我们可以把他按照x轴的升序分成多个子区域先在子区域中求最近点距离,然后将相邻两个子区域合并,看看两个子区域中有没有更小的。大致思想就是这样的。

    设计算法:递归将问题分成一小个问题。在找区域里面的最近点先将他按照x或y轴升或者降序排序这样找就可以省时间,详见代码,先看题,再看代码。


    有错的地方还望指出,多多来hack

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <string>
     5 #include <algorithm>
     6 #include <stdlib.h>
     7 #include <cmath>
     8 
     9 using namespace std;
    10 const int MM = 100005;
    11 const double INF=1e20;
    12 struct Points
    13 {
    14     double x,y;
    15 };
    16 Points point[MM];
    17 bool cmpx(Points x,Points y)
    18 {
    19     return x.x<y.x;
    20 }
    21 bool cmpy(int a,int b)
    22 {
    23     return point[a].y<point[b].y;
    24 }
    25 int n,index[MM];
    26 double dist(Points a,Points b)//返回两点距离 double 类型
    27 {
    28     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    29 }
    30 double closest_point(int l,int r)  //--------------------
    31 {
    32     double d=INF,d1,d2;
    33     if(l==r) return d;
    34     else if(l+1==r) return dist(point[l],point[r]);
    35     int mid=(l+r)>>1;
    36     d=min(closest_point(l,mid),closest_point(mid+1,r));//递归分解问题,找到子区域中的最近点距离
    37     /*****************找到后,以他们的最近距离来分割区间************************/
    38     int i,j,cut=0;
    39     for(i=l; i<=r; i++)
    40     {
    41         if(fabs(point[i].x-point[mid].x)<d)
    42             index[cut++]=i;
    43     }
    44     //在区间里找x宽度小于最近距离的把他的下标存在index数组里面
    45 
    46     sort(index,index+cut,cmpy);
    47     for(i=0; i<cut; i++)
    48     {
    49         for(j=i+1; j<cut; j++)
    50         {
    51             if(fabs(point[index[i]].y-point[index[j]].y)>=d)
    52                 break;
    53             //sort之后,只要当前超过了了,后面的数字一点不可能比这个小,所以不找,省时间
    54             d=min(dist(point[index[i]],point[index[j]]),d);
    55         }
    56     }
    57     return d;
    58 }
    59 int main()
    60 {
    61     while(scanf("%d",&n)!=EOF&&n)
    62     {
    63         int i;
    64         for(i=0; i<n; i++)
    65         {
    66             scanf("%lf %lf",&point[i].x,&point[i].y);
    67         }
    68         sort(point,point+n,cmpx);
    69         printf("%.2lf
    ",closest_point(0,n-1)/2);
    70     }
    71     return 0;
    72 }
    View Code
  • 相关阅读:
    Next.js文档自定义App、Document,getInitialProps翻译
    使用fetch进行数据请求时报json错误
    菜单制作:ul li横向排列
    Django Auth组件->扩展用户
    001.Django_Model.整理
    PyCharm中的django项目的引入
    Css3 里的弹性盒的比例关系
    vue的组件通讯 父传子 -- 子传父-- 兄弟组件的传值 vue的组件传值
    新手如何创建一个vue项目 ---vue---新手创建第一个项目
    如何自学计算机前端开发?精细的自学步骤是什么样的?
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7208011.html
Copyright © 2011-2022 走看看