题目大意:

给定一堆点集,在这一堆点集中找到一组点集它们之间的距离达到最短

对于HDU1007因为求圆的半径,所以距离还要除以2

普通情况下,可以将nge点,将任意两个点之间的距离都算一遍,在循环过程中,每次取到距离的较小值

但数据量大的话,这种O(n^2)的方法肯定是不合理的

转化为O(nlogn)的方法是可取的

这里采用分治的方法

我们希望尽可能的均匀分配,也就是让左右两端所含有的点的数目一样多,所以一开始就根据以x优先排序 , 然后取中值作为分割边

int fenzhi(int l , int r)

{

  int m = (l+r) >> 1;

  int d1 = fenzhi(l , m);

  int d2 = fenzhi(m+1 , r);

  int d3 = 左右两部分的点相互作距离运算得到  //也就是一个合并的过程

  return min(d1 , d2 , d3);

}

当l == r时 无疑距离不存在,我们返回一个最大值maxn即可不会影响结果

当l == r-1说明只存在两个点, 那就是将这两个点的距离作为最短距离返回即可

由于是自底向下

我们可以根据d1 , d2 , 优先得到d = min(d1 , d2)

那样我们在合并的过程中只要找距离小于d的点就可以了,我们不能将所有点都访问一遍,但是我们可以控制一个范围

先找到所有离分割线距离小于d的点,也即左侧的图所示,超出那个范围的话必然左右两个点相连距离大于d

找到所有符合点将其下标用rec数组保存即可

然后将rec数组中的点全都比较一遍,比较过程中可以先只关注两点在y轴上的距离是否小于d , 是的话计算距离,并且与原距离取最小值

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100005
#define maxn 2000000000 struct Point{
double x , y;
//利用减法运算计算两点间的距离
double operator-(const Point &m)const{
return sqrt((x-m.x)*(x-m.x) + (y-m.y)*(y-m.y));
}
}p[N]; bool cmpxy(const Point &m1 , const Point &m2){
if(m1.x == m2.x) return m1.y < m2.y;
return m1.x < m2.x;
} //d要随之更改,所以参数要引用传递
void merge_l_r(double &d , int l , int r)
{
int m = (l+r) >> ;
/*得到所有离分割线距离不大于d的点,否则本身到分割线就大于d,那么左右两侧相连必然大于d
就没有保留下去的必要了*/
int rec[N] , k = ;//记录所有符合点的编号
for(int i = l ; i<=r ; i++){
if(p[m] - p[i] < d)
rec[k++] = i;
} //有见到别人博客在这里将rec根据对应点的y的大小排了一次序,但我提交了好像时间反而更长就干脆不用了
/*
大致如下:
现在最外面写个
bool cmpxy(const Point &m1 , const Point &m2){
if(m1.x == m2.x) return m1.y < m2.y;
return m1.x < m2.x;
}
这个位置写个sort(rec , rec+k , cmpy);
*/
for(int i= ; i<k ; i++){
for(int j=i+ ; j<k ; j++){
if(abs(p[rec[j]].y - p[rec[i]].y) < d)
d = min(d , p[rec[j]] - p[rec[i]]);
}
}
} double fenzhi(int l , int r)
{
int m = (l+r) >> ;
//这里是计算两点的最短距离,l==r只有一个点存在,所以输出一个最大距离使其不影响结果
if(l == r) return maxn;
if(l == r-) return p[l] - p[r]; double d;
//处理左边
double d1 = fenzhi(l , m);
//处理右边
double d2 = fenzhi(m+ , r);
//得到左右两部分中两点间的最小值
d = min(d1 , d2); //将这个最小值和左右两部分的点相连得到的最小边作比较
merge_l_r(d , l , r); return d;
} int main()
{
int n;
while(scanf("%d" , &n) , n){
for(int i = ; i<n ; i++){
scanf("%lf%lf" , &p[i].x , &p[i].y);
}
sort(p , p+n , cmpxy);
//这里是取圆的半径所以除以二
printf("%.2f\n" , fenzhi( , n-) / );
}
return ;
}

  

最接近的点配对(分治问题理解) && HDU 1007代码的更多相关文章

  1. 学点Groovy来理解build.gradle代码

    在写这篇博客时,搜索参考了很多资料,网上对于 Groovy 介绍的博客已经特别多了,所以也就没准备再详细的去介绍 Groovy,本来也就计划写一些自己认为较重要的点.后来发现了 Groovy 的官方文 ...

  2. 原 CNN--卷积神经网络从R-CNN到Faster R-CNN的理解(CIFAR10分类代码)

    1. 什么是CNN 卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Netwo ...

  3. php代码规范->如何写出规范且易于理解的项目代码-ZX版

    2019年5月17日10:50:12 前序: 目前是想到哪写到哪,后面有时间在整理成具体文章 很多时候,PHP代码风格过于自由,导致一个项目有N多种写法风格,有些人为了自己认为的技术"高&q ...

  4. 如何理解这段代码:void (*signal (int sinno,void(*func)(int)))(int)

    void (*signal (int sinno,void(*func)(int)))(int) 先来看void(*func)(int)   这里的意思是声明一个函数指针func,它的参数类型为int ...

  5. .net中值类型、引用类型理解的c#代码示例

    下面是以前在公司的时候给别人讲解值类型.引用类型时创建的c#代码示例,从实际使用时的角度出发,对于初学者还是很有帮助的.这里并没有深入讲解值类型包含引用类型成员时(如struct)在内存中的存放情况等 ...

  6. HDU 1007 Quoit Design【计算几何/分治/最近点对】

    Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  7. Java深度理解——Java字节代码的操纵

    导读:Java作为业界应用最为广泛的语言之一,深得众多软件厂商和开发者的推崇,更是被包括Oracle在内的众多JCP成员积极地推动发展.但是对于 Java语言的深度理解和运用,毕竟是很少会有人涉及的话 ...

  8. HDU 1007 平面上最近点对 分治

    思路: 分治 套路题 //By SiriusRen #include <cmath> #include <cstdio> #include <algorithm> ...

  9. HDU 1007:Quoit Design(分治求最近点对)

    http://acm.hdu.edu.cn/showproblem.php?pid=1007 题意:平面上有n个点,问最近的两个点之间的距离的一半是多少. 思路:用分治做.把整体分为左右两个部分,那么 ...

随机推荐

  1. bzoj 1232: [Usaco2008Nov]安慰奶牛cheer【最小生成树】

    有趣 每条边在算答案的时候被算了二倍的边权值加上两个端点的权值,然后睡觉点额外加一次 所以可以用这个权做MST,然后加上点权最小的点 #include<iostream> #include ...

  2. 【weiphp】安装中报错

    问题描述:安装的第三部报错“SQLSTATE[HY000]: General error: 2030 This command is not supported in the prepared sta ...

  3. 【JS】温故知新: 从parseInt开始

    工作中,几乎习惯了大量使用方便的工具库(如underscore.lodash),但是长期的依赖,却有可能在我们注意不到的地方出现黑天鹅,笔者最近就碰到了这样一件例子: parseInt(9e-10); ...

  4. 【杂谈】HTML5到底给了我们什么?迟到的2016年终总结

    其实提笔的时候日期已经到了3月了,不过由于在过去的2016年笔者发生了蛮多的事情,所以还是决定记录一下,那些关于成长的片段. 其实HTML5是在2012年的时候接触的,当时和结果志趣相投的同事,看到了 ...

  5. [C++ STL] 常用算法总结

    1 概述 STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<alg ...

  6. 如何在Ubuntu上安装Wine 2.6

    Wine(Wine不是模拟器)是一种开源兼容层软件应用程序,可以让Linux和Unix用户通过Winelib软件库在他们的系统上运行Windows软件. sudo add-apt-repository ...

  7. 数学 FZU 2074 Number of methods

    题目传送门 /* 数学:假设取了第i个,有C(n-1)(i-1)种取法 则ans = sum (C(n-1)(i-1)) (1<i<=n) 即2^(n-1) */ #include < ...

  8. redis学习-字典

    1.字典作用 实现数据库键空间(key space): 用作 Hash 类型键的底层实现之一: 2.字典实现的数据结构 typedef struct dict { // 特定于类型的处理函数 dict ...

  9. 前端--3、jQuery

    介绍 jQuery是一个Javascript框架.其宗旨是——WRITE LESS,DO MORE! 是轻量级的js库,兼容CSS3和各种浏览器. 作用:处理HTMLdocuments.events. ...

  10. 通过重写.htaccess文件添加404

    如果说是用linux服务器的系统 想要给自己的网站设置404怎么弄?如果你不会给自己的Ecs服务器添加服务器管理系统,或是你购买的云虚拟主机没有304.404设置,那么就要通过自己重写文件来设置404 ...