hdu 4347 The Closest M Points(KD树)
一道KNN的题。直接用kd树加上一个暴力更新就撸过去了。写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天。
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; const int K = ;
const int N = ;
int dm, cdm;
template<class T> T sqr(T x) { return x * x;}
struct Node {
int x[K];
Node *c[];
bool operator < (Node a) const {
for (int i = ; i < dm; i++) if (x[(cdm + i) % dm] != a.x[(cdm + i) % dm]) return x[(cdm + i) % dm] < a.x[(cdm + i) % dm];
return true;
}
} node[N]; int dist(Node *a, Node *b) {
int ret = ;
for (int i = ; i < dm; i++) ret += sqr(a->x[i] - b->x[i]);
return ret;
} struct KDT {
Node *knn[];
int top, dis[], sz;
Node *RT;
void build(int l, int r, int dp, Node *&rt) {
cdm = dp % dm;
if (l > r) { rt = NULL; return ;}
int m = l + r >> ;
nth_element(node + l, node + m, node + r + );
rt = node + m;
build(l, m - , dp + , rt->c[]);
build(m + , r, dp + , rt->c[]);
}
void build(int l, int r) {
sz = r - l + ;
build(l, r, , RT);
}
void search(int dp, Node *x, Node *rt, int k) {
if (!rt) return ;
cdm = dp % dm;
int d = dist(x, rt), p = top;
while (p >= && d < dis[p]) dis[p + ] = dis[p], knn[p + ] = knn[p], p--;
p++;
dis[p] = d;
knn[p] = rt;
if (top + < k) top++;
bool r = x->x[cdm] >= rt->x[cdm];
search(dp + , x, rt->c[r], k);
cdm = dp % dm;
if (top + < k || sqr(rt->x[cdm] - x->x[cdm]) < dis[top]) search(dp + , x, rt->c[!r], k);
}
void search(Node *x, int k) {
top = -;
search(, x, RT, k);
}
void pre(Node *x) {
if (!x) return ;
pre(x->c[]);
cout << x->x[] << ' ' << x->x[] << endl;
pre(x->c[]);
}
} kdt; int main() {
int n, m, k;
Node tmp;
while (~scanf("%d%d", &n, &dm)) {
for (int i = ; i < n; i++) {
for (int j = ; j < dm; j++) scanf("%d", node[i].x + j);
node[i].c[] = node[i].c[] = NULL;
}
kdt.build(, n - );
scanf("%d", &m);
while (m--) {
for (int i = ; i < dm; i++) scanf("%d", tmp.x + i);
scanf("%d", &k);
kdt.search(&tmp, k);
printf("the closest %d points are:\n", k);
for (int i = ; i <= kdt.top; i++) {
for (int j = ; j < dm; j++) {
if (j) putchar(' ');
printf("%d", kdt.knn[i]->x[j]);
}
puts("");
}
}
}
return ;
}
——written by Lyon
hdu 4347 The Closest M Points(KD树)的更多相关文章
- bzoj 3053 HDU 4347 : The Closest M Points kd树
bzoj 3053 HDU 4347 : The Closest M Points kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差 ...
- hdu 4347 The Closest M Points (kd树)
版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出 . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说, ...
- 数据结构(KD树):HDU 4347 The Closest M Points
The Closest M Points Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 98304/98304 K (Java/Ot ...
- HDU 4347 - The Closest M Points - [KDTree模板题]
本文参考: https://www.cnblogs.com/GerynOhenz/p/8727415.html kuangbin的ACM模板(新) 题目链接:http://acm.hdu.edu.cn ...
- HDU 4347 The Closest M Points (kdTree)
赤果果的kdTree. 学习传送门:http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html 其实就是二叉树的变形 #includ ...
- 【HDOJ】4347 The Closest M Points
居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...
- BZOJ 3053: The Closest M Points(K-D Tree)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1235 Solved: 418[Submit][Status][Discuss] Descripti ...
- [hdu4347]The Closest M Points(线段树形式kd-tree)
解题关键:kdtree模板题,距离某点最近的m个点. #include<cstdio> #include<cstring> #include<algorithm> ...
- BZOJ3053:The Closest M Points(K-D Teee)
Description The course of Software Design and Development Practice is objectionable. ZLC is facing a ...
随机推荐
- Python爬虫之selenium库使用详解
Python爬虫之selenium库使用详解 本章内容如下: 什么是Selenium selenium基本使用 声明浏览器对象 访问页面 查找元素 多个元素查找 元素交互操作 交互动作 执行JavaS ...
- itextsharp 1.0
1 效果图 2.代码 引用组件: using iTextSharp.text;using iTextSharp.text.pdf;using System;using System.Data;usin ...
- 转搞定python多线程和多进程
转自https://www.cnblogs.com/whatisfantasy/p/6440585.html 1 概念梳理: 1.1 线程 1.1.1 什么是线程 线程是操作系统能够进行运算调度的最小 ...
- oracle 索引监控
索引对于在大量数据里检索出少量数据库的查询操作来说是高效的,可是对于DML操作来说.却是负面的:①其对于insert 操作的反面影响最大.该表的索引越多,更新的索引越多,insert 操 ...
- 实现一个vue的图片预览插件
vue-image-swipe 基于photoswipe实现的vue图片预览组件 安装 1 第一步 npm install vue-image-swipe -D 2 第二步 vue 入口文件引入 im ...
- to_char 中fm
1,有9的地方如果有数字就显示如果没有数字就不显示,有0的地方在没有数字的时候也会有0来占位 select to_char(9999.09556,'fm99999.0900'),to_char(99 ...
- 优化SQL之最佳索引
SQL优化工具Tosska SQL Tuning Expert for Oracle,帮助SQL开发人员解决SQL性能问题. 本工具主要创始人Richard To, 资深ITPUB元老,从1996年开 ...
- Redis 源码学习之 Redis 事务Nosql
Redis事务提供了一种将多个命令请求打包,然后一次性.按照顺序地执行多个命令的机制,并且在事务执行的期间,服务器不会中断事务而去执行其他不在事务中的命令请求,它会把事务中所有的命令都执行完毕才会去执 ...
- C++之以分隔符的形式获取字符串
void CConvert::Split(const std::string& src, const std::string& separator, std::vector<st ...
- day39 09-Spring的AOP:基于AspectJ的通知类型
AspectJ的六种通知的类型,最后一种不讲,只讲前五种. 环绕通知是可以阻止目标方法执行的. <?xml version="1.0" encoding="UT ...