Problem - 4347

  一道KNN的题。直接用kd树加上一个暴力更新就撸过去了。写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天。

代码如下:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. const int K = ;
  10. const int N = ;
  11. int dm, cdm;
  12. template<class T> T sqr(T x) { return x * x;}
  13. struct Node {
  14. int x[K];
  15. Node *c[];
  16. bool operator < (Node a) const {
  17. 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];
  18. return true;
  19. }
  20. } node[N];
  21.  
  22. int dist(Node *a, Node *b) {
  23. int ret = ;
  24. for (int i = ; i < dm; i++) ret += sqr(a->x[i] - b->x[i]);
  25. return ret;
  26. }
  27.  
  28. struct KDT {
  29. Node *knn[];
  30. int top, dis[], sz;
  31. Node *RT;
  32. void build(int l, int r, int dp, Node *&rt) {
  33. cdm = dp % dm;
  34. if (l > r) { rt = NULL; return ;}
  35. int m = l + r >> ;
  36. nth_element(node + l, node + m, node + r + );
  37. rt = node + m;
  38. build(l, m - , dp + , rt->c[]);
  39. build(m + , r, dp + , rt->c[]);
  40. }
  41. void build(int l, int r) {
  42. sz = r - l + ;
  43. build(l, r, , RT);
  44. }
  45. void search(int dp, Node *x, Node *rt, int k) {
  46. if (!rt) return ;
  47. cdm = dp % dm;
  48. int d = dist(x, rt), p = top;
  49. while (p >= && d < dis[p]) dis[p + ] = dis[p], knn[p + ] = knn[p], p--;
  50. p++;
  51. dis[p] = d;
  52. knn[p] = rt;
  53. if (top + < k) top++;
  54. bool r = x->x[cdm] >= rt->x[cdm];
  55. search(dp + , x, rt->c[r], k);
  56. cdm = dp % dm;
  57. if (top + < k || sqr(rt->x[cdm] - x->x[cdm]) < dis[top]) search(dp + , x, rt->c[!r], k);
  58. }
  59. void search(Node *x, int k) {
  60. top = -;
  61. search(, x, RT, k);
  62. }
  63. void pre(Node *x) {
  64. if (!x) return ;
  65. pre(x->c[]);
  66. cout << x->x[] << ' ' << x->x[] << endl;
  67. pre(x->c[]);
  68. }
  69. } kdt;
  70.  
  71. int main() {
  72. int n, m, k;
  73. Node tmp;
  74. while (~scanf("%d%d", &n, &dm)) {
  75. for (int i = ; i < n; i++) {
  76. for (int j = ; j < dm; j++) scanf("%d", node[i].x + j);
  77. node[i].c[] = node[i].c[] = NULL;
  78. }
  79. kdt.build(, n - );
  80. scanf("%d", &m);
  81. while (m--) {
  82. for (int i = ; i < dm; i++) scanf("%d", tmp.x + i);
  83. scanf("%d", &k);
  84. kdt.search(&tmp, k);
  85. printf("the closest %d points are:\n", k);
  86. for (int i = ; i <= kdt.top; i++) {
  87. for (int j = ; j < dm; j++) {
  88. if (j) putchar(' ');
  89. printf("%d", kdt.knn[i]->x[j]);
  90. }
  91. puts("");
  92. }
  93. }
  94. }
  95. return ;
  96. }

——written by Lyon

hdu 4347 The Closest M Points(KD树)的更多相关文章

  1. bzoj 3053 HDU 4347 : The Closest M Points kd树

    bzoj 3053 HDU 4347 : The Closest M Points  kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差 ...

  2. hdu 4347 The Closest M Points (kd树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出  . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说, ...

  3. 数据结构(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 ...

  4. HDU 4347 - The Closest M Points - [KDTree模板题]

    本文参考: https://www.cnblogs.com/GerynOhenz/p/8727415.html kuangbin的ACM模板(新) 题目链接:http://acm.hdu.edu.cn ...

  5. HDU 4347 The Closest M Points (kdTree)

    赤果果的kdTree. 学习传送门:http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html 其实就是二叉树的变形 #includ ...

  6. 【HDOJ】4347 The Closest M Points

    居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...

  7. BZOJ 3053: The Closest M Points(K-D Tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1235  Solved: 418[Submit][Status][Discuss] Descripti ...

  8. [hdu4347]The Closest M Points(线段树形式kd-tree)

    解题关键:kdtree模板题,距离某点最近的m个点. #include<cstdio> #include<cstring> #include<algorithm> ...

  9. BZOJ3053:The Closest M Points(K-D Teee)

    Description The course of Software Design and Development Practice is objectionable. ZLC is facing a ...

随机推荐

  1. Linux ifconfig 配置网络接口

    Linux ifconfig 可以用来配置网络接口的IP地址.掩码.网关.物理地址等:值得一说的是用Linux ifconfig 为网卡指定IP地址,这只是用来调试网络用的,并不会更改系统关于网卡的配 ...

  2. Entrust - Laravel 用户权限系统解决方案 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 - Powered by PHPHub

    说明# Zizaco/Entrust 是 Laravel 下 用户权限系统 的解决方案, 配合 用户身份认证 扩展包 Zizaco/confide 使用, 可以快速搭建出一套具备高扩展性的用户系统. ...

  3. Eclipse Git插件切换分支的时候不要Reset

    今天做了一件蠢事,我在当前分支上改了很多代码,后来切换分支的时候,有一个文件有冲突,eclipse提示这个文件冲突,我可以选择commit/stash/reset,我一看这个文件没什么关系,不需要提交 ...

  4. Ajax--同源策略,jsonp跨域传输原理(callback),

    什么是同源策略? 阮一峰的博客 同源策略 同源策略的解决方法: 跨域传输 img 标签的src是可以引入其他域名下的图片 script标签的src属性同理 ,也可以引入其他域名下的js文件,并执行 1 ...

  5. ListView设置的点点滴滴

    去掉ListView的分界线 1. ListView的属性Divider设为#FFCC00      这种对任何背景都适用 2. 把ListView的属性Divider设为和背景一样的颜色 3.and ...

  6. 如何在CentOS 7 / Fedora 31/30/29上安装ELK Stack

    原文地址:https://computingforgeeks.com/how-to-install-elk-stack-on-centos-fedora/ 原作者: Josphat Mutai 译者: ...

  7. python学习笔记09--线程、进程

    本节内容 一.进程与线程的概念 1.1进程 1.2线程 1.3进程与线程的区别 二.线程 2.1启一个线程 2.2线程的2种调用方式 2.3 join 2.4 守护线程Daemon 2.5线程锁 2. ...

  8. pygame-常用的方法

    1.pygame常用的方法 2.语音 图片

  9. 微信小程序分析见解

    前两天朋友圈都快被小程序给刷爆了: 对于小程序这方面,  由于没有公测的资格.所以翻阅了许许多多的资料,来了解一下小程序: 微信小程序: 小程序是一种不需要下载安装即可使用的应用,它实现了应用&quo ...

  10. nth-child和nth-of-type的使用案列

    HTML: <div id="footer-f"> <ul class="trajectory"> <li> <div ...