【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 ...
随机推荐
- IAR FOR STM8 学习笔记 固件库 GPIO
经过一番挣扎,还是决定使用官方的固件库了.. 从网上下一个STM8S的固件库,记得是FOR IAR的. 找到里面的IAR模板就可以开始用了. 这些都是直接写好的库函数,可以直接调用,但首先得先读懂,先 ...
- 洛谷 P2679 子串
题目背景 无 题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新 ...
- BZOJ3160: 万径人踪灭(FFT,回文自动机)
BZOJ传送门: 解题思路: FFT在处理卷积时可以将自己与自己卷,在某一种字母上标1其他标0,做字符集次就好了. (回文就是直接对称可以联系偶函数定义理解,根据这个性质就可以将字符串反向实现字符串匹 ...
- BZOJ2555: SubString(后缀自动机,LCT维护Parent树)
Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支 ...
- django 简单会议室预约(4)
基本的配置已经完成了,来看看最重要的views.py 先看看简单的注册登录功能,在django里有一个专门的模块用来验证用户信息 :所以只需要调用就好了: #-*-coding:utf-8 -*- f ...
- sql server还原数据库代码
RESTORE DATABASE ExaminationsystemFROM DISK = 'C:\Users\admin\Desktop\20140324.bak'with replace,MOVE ...
- get_browser()用法
get_browser()用法 get_browser()函数是用来分析USER_AGENT的,它的执行方法是自动获取客户端的USER_AGENT,然后调用browscap.ini库进行分析得到结果 ...
- TextView-属性大全(设置超链接颜色)
今天想要修改一个textview下的超链接的颜色值,自己当时在网上搜了一下,结果看到的全是怎么给一个textview中的部分内容设置颜色.下划线等.当时就以为在textview属性里面可能不存在设定超 ...
- Rotation--控件位置旋转
今天想要完成一个按钮的动画,也就是随着手势在屏幕上的滑动,让按钮图片跟着旋转.刚开始的思路是,先把图片旋转以后,在把这个图片设置为imagebutton的背景.不过,会发现这个图片经过处理以后一直变形 ...
- Java Web学习总结(4)——HttpServletResponse对象入门
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象. request和response对象即然代表请求和响应,那我们 ...