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;
}

  

最新文章

  1. 公司系统的license授权
  2. hibernate xx(tableName) is not mapped
  3. 无线客户端框架设计(2):项目结构的设计(iOS篇)
  4. 【BZOJ 3524】【Poi2014】Couriers 可持久化线段树
  5. OpenLayer 3 鹰眼控件和全屏显示
  6. Adobe RIA 开发工程师认证考试大纲
  7. OpenResty 执行阶段的概念和用途
  8. 第六十四天 JS基础操作
  9. 【1】【leetcode-77】 组合
  10. 结构体变量的 extern 使用方法,转--
  11. 接口测试工具SoapUI Pro5.1.2基本使用20150920
  12. HTTP及RFC解析。
  13. _mysql.c(42) : fatal error C1083: Cannot open include file: &#39;config-win.h&#39;:问题的解决
  14. 怎样设置IIS6.0的闲置超时时间
  15. 解决由AJAX请求时forms认证实效的重新认证问题
  16. Java课后思考题
  17. maven安装和与IDE集成
  18. POJ-3662 Telephone Lines---二分+最短路+最小化第k+1大
  19. 重构改善既有代码设计--重构手法11:Move Field (搬移字段)
  20. hadoop常见问题总结1

热门文章

  1. ssh以bash登录的配置
  2. 在阿里云上遇见更好的Oracle(四)
  3. 感知机学习算法(PLA)
  4. 软件工程项目组Z.XML会议记录 2013/11/27
  5. 【tips】【词频统计】中可能用到的资源,以C++为例
  6. Python模块学习:logging 日志记录
  7. LTE中基于S1的切换
  8. esayui combotree 只能选择子节点
  9. VS 附加进程调试
  10. Codeforces Round #383 (Div. 1) C(二分图)