K-D树问题 HDU 4347
K-D树可以看看这个博客写的真心不错!这里存个版
http://blog.csdn.net/zhjchengfeng5/article/details/7855241
HDU 4349
#include <map>
//KD树学习http://blog.csdn.net/zhjchengfeng5/article/details/7855241
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
#define MAXN 100010
const LL INF = LONG_LONG_MAX;
struct node
{
LL pos[10];
int id;
}tree[MAXN],op,point;
int split[MAXN],N,now,demension;
bool used[MAXN];
LL ans,id;
double var[10];
bool cmp(const node &a,const node &b)
{
return a.pos[split[now]] < b.pos[split[now]];
}
void build(int L,int R)
{
if (L > R) return;
int mid = (L + R) / 2;
//求出每一唯上的方差
for (int pos = 0 ; pos < demension ; pos++)
{
double avg = var[pos] = 0;
for (int i = L ; i <= R; i++)
avg += tree[i].pos[pos];
avg /= (R - L + 1);
for (int i = L ; i <= R; i++)
var[pos] += (tree[i].pos[pos] - avg) * (tree[i].pos[pos] - avg);
var[pos] /= (R - L + 1);
}
//找到方差最大的那一个唯独
split[now = mid] = 0;
for (int i = 1; i < demension ; i++)
if (var[split[mid]] < var[i]) split[mid] = i;
nth_element(tree + L ,tree + mid,tree + R + 1,cmp);
build(L,mid - 1);
build(mid + 1,R);
}
void query(int L,int R)
{
if (L > R) return;
int mid = (L + R) / 2;
LL dis = 0;
//求出目标点到当前根节点的距
for (int i = 0 ; i < demension ; i++)
dis += (op.pos[i] - tree[mid].pos[i]) * (op.pos[i] - tree[mid].pos[i]);
//if (dis == 0) dis = INF;
//printf("%lld\n",dis);
//如果当前节点能够用来更新最近距离并且dis<ans
if (!used[tree[mid].id] && dis < ans)
{
ans = dis;
id = tree[mid].id;
point = tree[mid];
}
//计算op到分裂平面的距离
LL radius = (op.pos[split[mid]] - tree[mid].pos[split[mid]]) *
(op.pos[split[mid]] - tree[mid].pos[split[mid]]);
//对子区间进行查询
if (op.pos[split[mid]] < tree[mid].pos[split[mid]])
{
query(L,mid - 1);
if (radius <= ans) query(mid + 1,R);
}
else
{
query(mid + 1,R);
if (radius <= ans) query(L,mid - 1);
}
}
node ret[20];
int main()
{
// freopen("sample.txt","r",stdin);
while (scanf("%d%d",&N,&demension) != EOF)
{
for (int i = 1; i <= N; i++)
for (int j = 0 ;j < demension ; j++)
scanf("%lld",&tree[i].pos[j]);
for (int i = 1; i <= N; i++) tree[i].id = i;
build(1,N);
int T;
scanf("%d",&T);
for (int i = 1; i <= T; i++)
{
for (int j = 0; j < demension ; j++)
scanf("%lld",&op.pos[j]);
//printf("%lld %lld\n",op.pos[0],op.pos[1]);
memset(used,false,sizeof(used));
int m;
scanf("%d",&m);
for (int j = 0 ; j < m ; j++)
{
ans = INF;
query(1,N);
ret[j] = point;
//printf("%lld\n",id);
used[id] = true;
}
printf("the closest %d points are:\n",m);
for (int j = 0 ; j < m ; j++)
{
printf("%lld",ret[j].pos[0]);
for (int k = 1; k < demension ; k++)
printf(" %lld",ret[j].pos[k]);
putchar('\n');
}
}
}
return 0;
}
K-D树问题 HDU 4347的更多相关文章
- 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树的可以先看看这个 . 不多说, ...
- HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5412 Problem Description There are N boys in CodeLan ...
- hdu 4347 The Closest M Points(KD树)
Problem - 4347 一道KNN的题.直接用kd树加上一个暴力更新就撸过去了.写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天. ...
- 数据结构(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 5493 Queue (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5493 题目大意: N个人,每个人有一个唯一的高度h,还有一个排名r,表示它前面或后面比它高的人的个数 ...
- 【线段树】HDU 5443 The Water Problem
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5443 题目大意: T组数据.n个值,m个询问,求区间l到r里的最大值.(n,m<=1000) ...
- 狂K 线段树
想写好树剖~~线段树very important HDU 1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536 ...
随机推荐
- Python网络编程(进程通信、信号、线程锁、多线程)
什么是进程通讯的信号? 用过Windows的我们都知道,当我们无法正常结束一个程序时, 可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢? 同样的功能在Linux上是通过生成信号和捕获信号来实 ...
- Flask 学习笔记(二):RESTful API
概括 URL:需要操作的对象,也就是资源 HTTP method:我要对该对象做什么(POST 增.DELETE 删.GET 查.PUT 和 PATCH 改) HTTP status code:操作的 ...
- 【Python】python函数每日一讲 - dir()
最近确实是有些忙,刚过了年,积攒了很多事情需要处理,所以每日一函数只能是每两天更新一篇,在这里和大家致歉. 今天我们来看一个非常重要的函数:dir() 中文说明:不带参数时,返回当前范围内的变量.方法 ...
- sendto函数的坑
测试unix数据报套接字时,一个程序收,一个程序发,分别绑定自己的socket.结果在收的部分,返回的发送方的地址总是空的,但是返回的地址长度又是对的. ) { bzero(&clientad ...
- delphi如何模块内部获得自身路径ExtractFilePath和paramstr(0)
如何模块内部获得自身路径?Exe程序:DLL程序: ExtractFilePath(Application.ExeName) GetCurrentDir TIniFile.Create(GetCurr ...
- Nginx 学习笔记之安装篇
在windows下安装Nginx其实非常简单,只需如下几个步骤: 1. 在Nginx官网下载相应版本的安装程序,上面有最新版.稳定版等各种版本,正式运营的项目建议下载最新的稳定版 2.将下载后的压缩包 ...
- CSS继承—深入剖析
CSS的继承是指被包在内部的标签将拥有外部标签的样式性质.继承特性最典型的应用通常发挥在整个网页的样式预设,即整体布局声明.而需要要指定为其它样式的部份设定在个别元素里即可达到效果.这项特性可以给网页 ...
- BZOJ4597 SHOI2016随机序列(线段树)
先考虑题目所说的太简单了的问题.注意到只要把加减号相取反,就可以得到一对除了第一项都互相抵消的式子.于是得到答案即为Σf(i)g(i),其中f(i)为前缀积,g(i)为第i个数前面所有符号均填乘号,第 ...
- BZOJ4592 SHOI2015脑洞治疗仪(线段树)
考虑需要资瓷哪些操作:区间赋值为0:统计区间1的个数:将区间前k个0变为1:询问区间最长全0子串.于是线段树维护区间1的个数.0的个数.最长前缀后缀全0子串即可.稍微困难的是用一个log实现将区间前k ...
- 洛谷 P1379 八数码难题 解题报告
P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...