HDOJ1007
/**
最近点对问题,时间复杂度为O(n*logn*logn)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const double INF = 1e20;
const int N = ; struct Point
{
double x;
double y;
}point[N];
int n;
int tmpt[N]; bool cmpxy(const Point& a, const Point& b) //cmpxy这种写法只能和sort结合运用
{
if(a.x != b.x)
return a.x < b.x;
return a.y < b.y;
} bool cmpy(const int& a, const int& b) //cmpy这种写法只能和sort结合运用
{
return point[a].y < point[b].y;
} double min(double a, double b)
{
return a < b ? a : b;
} double dis(int i, int j)
{
return sqrt((point[i].x-point[j].x)*(point[i].x-point[j].x)
+ (point[i].y-point[j].y)*(point[i].y-point[j].y));
} double Closest_Pair(int left, int right)
{
double d = INF;
if(left==right)
return d;
if(left + == right)
return dis(left, right); //到最后会返回最小两点的距离-------1
int mid = (left+right)>>; //这个骚操作的意思:>>是右移运算符,5>>1 的意思是将5表示为二进制后把末尾的数删去,其最终效果等同于5/2,是用来取降位平均数的
double d1 = Closest_Pair(left,mid); //上接第一步,返回值给了d1,d2,然后进行以下一系列操作--------2
double d2 = Closest_Pair(mid+,right);
d = min(d1,d2);
int i,j,k=;
//分离出宽度为d的区间
for(i = left; i <= right; i++)
{
if(fabs(point[mid].x-point[i].x) <= d) //fabs 求浮点类型的绝对值,与abs有点相似 用 <d 虽然可能扩大复杂度,但是只有如此了
tmpt[k++] = i;
}
sort(tmpt,tmpt+k,cmpy);
//线性扫描
for(i = ; i < k; i++)
{
for(j = i+; j < k && point[tmpt[j]].y-point[tmpt[i]].y<d; j++) //在此步骤做真正的判断,所以虽然前面可能扩大了各种可能性,但到此处都会解决的
{
double d3 = dis(tmpt[i],tmpt[j]);
if(d > d3)
d = d3;
}
}
return d; //上接第二步,在完成操作以后继续返回给上一级调用的函数,也就是返回第二步---------3
} //从倒推来看整个函数的运行过程为1-2-3-2-3-2-3...... int main()
{
while(true)
{
scanf("%d",&n);
if(n==)
break;
for(int i = ; i < n; i++)
scanf("%lf %lf",&point[i].x,&point[i].y);
sort(point,point+n,cmpxy);
printf("%.2lf\n",Closest_Pair(,n-)/); //此处left和right均为下标,2是除在外面的。。。看错了
}
return ;
}
借鉴了大神的经验,并对c++不懂得语法进行了注释。
加一条,结构体名字和定义的结构体类的名字不能相同。
http://blog.csdn.net/lonelycatcher/article/details/7973046
HDOJ1007的更多相关文章
- HDOJ-1007 Quoit Design(最近点对问题)
http://acm.hdu.edu.cn/showproblem.php?pid=1007 给出n个玩具(抽象为点)的坐标 求套圈的半径 要求最多只能套到一个玩具 实际就是要求最近的两个坐标的距离 ...
- hdoj1007【几何】【未完待续】
题意: 在一个平面上有n(1e5)个点,然后求一个圆来包住这些点,求这个圆的最小半径. 思考: 要使一个圆直接包了这些点,没有任何思路..
- (模板)hdoj1007(分治求平面最小点对)
题目链接:https://vjudge.net/problem/HDU-1007 题意:给定n个点,求平面距离最小点对的距离除2. 思路:分治求最小点对,对区间[l,r]递归求[l,mid]和[mid ...
- poj3714 Raid(分治求平面最近点对)
题目链接:https://vjudge.net/problem/POJ-3714 题意:给定两个点集,求最短距离. 思路:在平面最近点对基础上加了个条件,我么不访用f做标记,集合1的f为1,集合2的f ...
随机推荐
- 20145225唐振远《网络对抗》 Web安全基础实践
20145225唐振远<网络对抗>Web安全基础实践 参考博客:20145215 卢肖明 基础问题回答 (1)SQL注入攻击原理,如何防御? SQL注入攻击就是通过把SQL命令插入到Web ...
- tf.equal的使用
tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的 import tensorflow as tf im ...
- tf.multiply()和tf.matmul()区别
(1)tf.multiply是点乘,即Returns x * y element-wise. (2)tf.matmul是矩阵乘法,即Multiplies matrix a by matrix b, p ...
- vim常用的配置
.vimrc配置 syntax enable syntax on set relativenumber set autoindent set tabstop=4 set expandtab " ...
- Python3基础 tuple 通过拆分元组向元组中加入新的元素
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- Python3基础 global 使函数中的局部变量升格为全局变量
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- 误把Linux运行级别设置为6后的解决方法【转】
本文转载自:http://www.wuji8.com/meta/841011126.html 误把Linux运行级别设置为6后的解决方法 我们知道,Linux有7个运行级别,而运行级别设置为6 ...
- HDU 2841 Visible Trees(容斥)题解
题意:有一块(1,1)到(m,n)的地,从(0,0)看能看到几块(如果两块地到看的地方三点一线,后面的地都看不到). 思路:一开始是想不到容斥...后来发现被遮住的地都有一个特点,若(a,b)有gcd ...
- Java8新特性:Function接口和Lambda表达式参考
Lambda基本:https://blog.csdn.net/wargon/article/details/80656575 https://www.cnblogs.com/hyyq/p/742566 ...
- 封装TeeChart控件
public class MyChart { //字段 private TChart tChart; /// <summary> /// 构造函数,默认不是3D效果 /// </su ...