Time Limit: 1 second

Memory Limit: 32 MB

【问题描述】

聚类方法要求将空间中的点集,按照一点的方式进行归类,要求每一类中的点集相互之间的距离足够的“近”。

    聚类的一般方法是选取某一个点P,并用一个距离r作为度量,只要空间中的点Q距离点P的距离不超过r时,我们说点Q和点P是属于同一类的。

    现在我们考虑这么一个问题:

    给定二维空间中的N个点,并给定一个点P,你的任务就是求出在给定这N个点的点集中,距离点P的距离不超过r的最近点的距离。点A(x1,y1)和点B(x2,y2)之间的距离定义为dis(A,B)=|x1-x2|+|y1-y2|。

【输入格式】

输入数据的第一行为两个整数N (10≤N≤100,000)和r(1≤r≤100),分别表示点集中一共有N个不同的点,最近距离必须不超过r。

    之后有N行,每行有两个整数X和Y(-10,000≤X,Y≤10,000),表示二维空间的一个点(X,Y)。

    之后一行有一个整数Q(1≤Q≤10,000),表示询问的次数,之后Q行,每行有两个整数Px和Py,表示询问在给定的N个点中,距离点(Px,Py)的距离不超过r的最近点的距离。

    距离点(Px,Py)的距离不超过r的点数不会超过100个。

【输出格式】

对于每个询问,输出最近距离,如果不存在最近点距离,输出“-1”。

【输入样例1】

    5 1
    1 3
    2 6
    5 3
    -1 5
    6 5
    2
    2 3
    3 2

【输出样例1】

    1
    -1

【题解】

KD-tree的讲解。请在目录里面选kdtree分类。就可以看到一遍详解的文章。

这道题就是要求最邻近的点距离。

如果直接用kd-tree的模板,没法过。最后一个点会超时。

我们在看到当前点离分界面的距离比当前更新到的最短距离小的时候。会往另外一个儿子方向走。

那么我们可以加一句if 离分界面的距离 > r 则不往另一个儿子走。

因为大于r了。往另一个方向走肯定不能得出小于r的结果。没必要更新。

就是变成曼哈顿距离了。

nth_element(a + begin, a + m, a + 1 + end, cmp);

的范围是左闭右开。

所以要加1.

然后m左边就全是小于|等于a[m],右边全部大于||等于m。

【代码】

#include <cstdio>
#include <algorithm>
#include <cmath> const int MAXN = 101000;
const int INF = 2100000000; using namespace std; struct data2
{
int wei[2];
}; int n, r, fenlie[MAXN] = { 0 },v,q,ans;
data2 a[MAXN],op;
double fc[2]; int cmp(data2 a, data2 b) //写成结构体比较好写比较函数。
{
if (a.wei[fenlie[v]] < b.wei[fenlie[v]])
return 1;
return 0;
} void build(int begin, int end)
{
if (begin >= end)
return;
int m = (begin + end) >> 1;
for (int i = 0; i <= 1; i++)
{
double x = 0;
for (int j = begin; j <= end; j++)
x += a[j].wei[i];
x /= (end - begin + 1);
fc[i] = 0;
for (int j = begin; j <= end; j++)
fc[i] += (a[j].wei[i] - x)*(a[j].wei[i] - x);
fc[i] /= (end - begin + 1);
}
if (fc[0] > fc[1])
fenlie[m] = 0;
else
fenlie[m] = 1;
v = m;
nth_element(a + begin, a + m, a + 1 + end, cmp);
build(begin, m - 1);
build(m + 1, end);
} void input_data()
{
scanf("%d%d", &n, &r);
for (int i = 1; i <= n; i++)
scanf("%d%d", &a[i].wei[0], &a[i].wei[1]);
build(1, n);
} void query(int begin, int end)
{
if (begin > end)
return;
int m = (begin + end) >> 1;
int dis = abs(a[m].wei[0] - op.wei[0]) + abs(a[m].wei[1] - op.wei[1]);
if (dis < ans)
ans = dis;
if (begin == end)
return;
dis = abs(a[m].wei[fenlie[m]] - op.wei[fenlie[m]]);
if (op.wei[fenlie[m]] < a[m].wei[fenlie[m]])
{
query(begin, m - 1);
if (ans > dis && dis < r) //加上一句小于r的判断。不满足就不进入那个儿子。
query(m + 1, end);
}
else
{
query(m + 1, end);
if (ans > dis && dis < r)
query(begin, m - 1);
}
} void output_ans()
{
scanf("%d", &q);
while (q--)
{
ans = INF;
scanf("%d%d", &op.wei[0], &op.wei[1]);
query(1, n);
if (ans <= r)
printf("%d\n", ans);
else
printf("-1\n");
}
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
input_data();
output_ans();
return 0;
}

【t010】最近距离的更多相关文章

  1. OJ题解记录计划

    容错声明: ①题目选自https://acm.ecnu.edu.cn/,不再检查题目删改情况 ②所有代码仅代表个人AC提交,不保证解法无误 E0001  A+B Problem First AC: 2 ...

  2. iOS之计算上次日期距离现在多久, 如 xx 小时前、xx 分钟前等

    /**  *  计算上次日期距离现在多久  *  *  @param lastTime    上次日期(需要和格式对应)  *  @param format1     上次日期格式  *  @para ...

  3. 挑子学习笔记:对数似然距离(Log-Likelihood Distance)

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/log-likelihood_distance.html 本文是“挑子”在学习对数似然距离过程中的笔记摘录,文 ...

  4. 字符串编辑距离(Levenshtein距离)算法

    基本介绍 Levenshtein距离是一种计算两个字符串间的差异程度的字符串度量(string metric).我们可以认为Levenshtein距离就是从一个字符串修改到另一个字符串时,其中编辑单个 ...

  5. [LeetCode] Rearrange String k Distance Apart 按距离为k隔离重排字符串

    Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...

  6. [LeetCode] Shortest Word Distance III 最短单词距离之三

    This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...

  7. [LeetCode] Shortest Word Distance II 最短单词距离之二

    This is a follow up of Shortest Word Distance. The only difference is now you are given the list of ...

  8. ReactNative 根据scrollView/listview滑动距离动态修改NavBar颜色

    我们常见某些APP上滑的时候,NavBar颜色会从透明渐变为某种颜色 原理非常简单,根据scrollView的回调动态修改NavBar的透明度即可. 在RN中,尤其是ListView中这个回调不是很好 ...

  9. sql server2008根据经纬度计算两点之间的距离

    --通过经纬度计算两点之间的距离 create FUNCTION [dbo].[fnGetDistanceNew] --LatBegin 开始经度 --LngBegin 开始维度 --29.49029 ...

随机推荐

  1. HDU 4010 Query on The Trees (动态树)(Link-Cut-Tree)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4010 题意; 先给你一棵树,有 \(4\) 种操作: 1.如果 \(x\) 和 \(y\) 不在同一 ...

  2. 65.十一级指针实现百万qq号的增删查改以及排序写入

    运行结果: 内存使用情况: 写入文件排序好的数据: 创建文件地址以及创建十一级指针 char *path = "QQ.txt"; char *sortpath = "QQ ...

  3. UVA 11488 Hyper Prefix Sets (字典树)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. vue打包添加样式兼容前缀

    在ios8 版本上的h5对flex的支持不太好,需要有兼容的写法. vue-cli自带了postCss autoprefixer 进行兼容处理,配置如下 在vue-loader.config.js中开 ...

  5. CF741DArpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(DSU on tree)

    题目大意: 给定一个以1为根的树,每条路径上都有一个字符(a~v共22个)询问对于每一个子树内最长的路径上字母经排序后可以形成回文串的最长路径多长 解题思路: 假定给你一个字符串,如何判定其经打乱能否 ...

  6. MySQL主从同步配置(详细图解)

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 目录 一丶叙述 二丶备份主服务器原有数据到从服务器 三丶配置主服务器master(192.168.4.63) 四丶配置从服务器sl ...

  7. 【MongoDB】The connection between two tables

    In mongoDB, there are two general way to connect with two tables. Manual Connection and use DBRef 1. ...

  8. 学习活动管理系统:LAMS

    学习活动管理系统:LAMS 一.总结 基于java的cms 二.LAMS Learning Activity Management System,学习活动管理系统. 数字化学习已经具有完整的发展方法来 ...

  9. 19. Spring Boot Shiro 权限管理

    转自:https://blog.csdn.net/catoop/article/details/50520958

  10. C/S与B/S架构比较

    一C/S 1.C/S概念 C/S是Client/Server的缩写.服务器通常采用高性能的PC.工作站或小型机,并采用大型数据库系统,如Oracle.Sybase.Informix或 SQL Serv ...