【t010】最近距离
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】最近距离的更多相关文章
- OJ题解记录计划
容错声明: ①题目选自https://acm.ecnu.edu.cn/,不再检查题目删改情况 ②所有代码仅代表个人AC提交,不保证解法无误 E0001 A+B Problem First AC: 2 ...
- iOS之计算上次日期距离现在多久, 如 xx 小时前、xx 分钟前等
/** * 计算上次日期距离现在多久 * * @param lastTime 上次日期(需要和格式对应) * @param format1 上次日期格式 * @para ...
- 挑子学习笔记:对数似然距离(Log-Likelihood Distance)
转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/log-likelihood_distance.html 本文是“挑子”在学习对数似然距离过程中的笔记摘录,文 ...
- 字符串编辑距离(Levenshtein距离)算法
基本介绍 Levenshtein距离是一种计算两个字符串间的差异程度的字符串度量(string metric).我们可以认为Levenshtein距离就是从一个字符串修改到另一个字符串时,其中编辑单个 ...
- [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 ...
- [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 ...
- [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 ...
- ReactNative 根据scrollView/listview滑动距离动态修改NavBar颜色
我们常见某些APP上滑的时候,NavBar颜色会从透明渐变为某种颜色 原理非常简单,根据scrollView的回调动态修改NavBar的透明度即可. 在RN中,尤其是ListView中这个回调不是很好 ...
- sql server2008根据经纬度计算两点之间的距离
--通过经纬度计算两点之间的距离 create FUNCTION [dbo].[fnGetDistanceNew] --LatBegin 开始经度 --LngBegin 开始维度 --29.49029 ...
随机推荐
- battery-获取手机电量信息
我们如果想要获得手机的电池电量信息,可以借助广播来实现.因为当手机电池电量发生变化的时候,系统会发送一个广播.具体代码如下 //注册 intentFilter.addAction(Intent.ACT ...
- ubuntu-通配符
ubuntu下的通配符主要有三个 1.* 这个是匹配任意一个或多个字符 ab1.txt ab2.txt ab3.txt abc.txt 执行命令以及结果如下 zhangshuli@zhangshul ...
- ListView- 最后一行添加控件
今天在做一个功能的时候,要求必须是在一个listview下,有一段提示行的文字,自己的那个listview的adapter用的是cursoradapter,这样的话,处理布局的灵活性就大打折扣了.最开 ...
- 《ASP.NET》数据绑定—DropDownList、ListBox
DropDownList和ListBox实现两级联动功能.他们也能够将从后台数据库中搜选的出来的信息加以绑定.这里要实现的功能是在DropDownList中选择"省",然后让Lis ...
- Linux下改动Oracle数据库字符集命令
常见情形:从server备份Oracle数据库后再到本地机器上还原Oracle数据库的时候常常会碰见数据库字符编码不一致的情况,能够用下面命令来改动本地的Oracle数据库字符编码,然后顺利还原Ora ...
- node中间层
node中间层 一.总结 1.node中间层作用:前端也是mvc,NodeJS之后,前端可以更加专注于视图层,而让更多的数据逻辑放在Node层处理 2.node中间层作用:当发现所有请求量太多应付不过 ...
- Spring学习总结(7)——applicationContext.xml 配置文详解
web.xml中classpath:和classpath*: 有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件 ...
- Des 加密cbc模式 padding
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...
- macOS 上配置 Lua
[最新版]从零开始在 macOS 上配置 Lua 开发环境 脚本语言,你可能更需要的是 Lua 不同的脚本语言有不同的特性,第一接触的脚本语言,可能会影响自己对整个脚本语言的理解和认知.我以前接触 ...
- oled的一套stm32实验1
详细的oled介绍:http://blog.sina.com.cn/s/blog_57ad1bd20102wtq8.html 整理自:https://www.cnblogs.com/wp2312139 ...