HDU 5992/nowcoder 207K - Finding Hotels - [KDTree]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5992
题目链接:https://www.nowcoder.com/acm/contest/207/K
Problem Description
There are N hotels all over the world. Each hotel has a location and a price. M guests want to find a hotel with an acceptable price and a minimum distance from their locations. The distances are measured in Euclidean metric.
Input
The first line is the number of test cases. For each test case, the first line contains two integers N (N ≤ 200000) and M (M ≤ 20000). Each of the following N lines describes a hotel with 3 integers x (1 ≤ x ≤ N), y (1 ≤ y ≤ N) and c (1 ≤ c ≤ N), in which x and y are the coordinates of the hotel, c is its price. It is guaranteed that each of the N hotels has distinct x, distinct y, and distinct c. Then each of the following M lines describes the query of a guest with 3 integers x (1 ≤ x ≤ N), y (1 ≤ y ≤ N) and c (1 ≤ c ≤ N), in which x and y are the coordinates of the guest, c is the maximum acceptable price of the guest.
Output
For each guests query, output the hotel that the price is acceptable and is nearest to the guests location. If there are multiple hotels with acceptable prices and minimum distances, output the first one.
Sample Input
2
3 3
1 1 1
3 2 3
2 3 2
2 2 1
2 2 2
2 2 3
5 5
1 4 4
2 1 2
4 5 3
5 2 1
3 3 5
3 3 1
3 3 2
3 3 3
3 3 4
3 3 5
Sample Output
1 1 1
2 3 2
3 2 3
5 2 1
2 1 2
2 1 2
1 4 4
3 3 5
题意:
给出 $N$ 个酒店,每个酒店有坐标 $(x,y)$,价格为 $c$;同时又给出 $M$ 个人,同样每个人都有坐标 $(x,y)$,每个人能接收的最高酒店价格为 $c$;
每个人会选择不高于自己可接受价格的酒店中最近的那一个,如果同时有多个酒店同样最近,选择编号的那一个。
题解:
根据题目里的费用要求和同距离输出编号最小酒店两个要求,对KDTree模板进行一点小修改即可。
AC代码:
#include<bits/stdc++.h>
using namespace std; const int maxn=2e5+;
const int maxdim=; namespace KDTree
{
int K;//维数
inline double sqr(double x){return x*x;}
struct Point
{
int x[maxdim];
int c;
int idx;
double distance(const Point &oth)const
{
double ret=;
for(int i=;i<K;i++) ret+=sqr(x[i]-oth.x[i]);
return ret;
}
void input(int _idx)
{
idx=_idx;
for(int i=;i<K;i++) scanf("%d",&x[i]);
scanf("%d",&c);
}
void output()
{
for(int i=;i<K;i++) printf("%d ",x[i]);
printf("%d\n",c);
}
};
struct cmpx
{
int div;
cmpx(const int &_div){div=_div;}
bool operator()(const Point &a,const Point &b)
{
for(int i=;i<K;i++)
{
int k=(div+i)%K;
if(a.x[k]!=b.x[k]) return a.x[k]<b.x[k];
}
return true;
}
};
inline bool cmp(const Point &a,const Point &b,int div)
{
cmpx cp=cmpx(div);
return cp(a,b);
} struct Node //KDTree的节点
{
Point e;
Node *lc,*rc;
int div;
}pool[maxn],*tail,*root;
void init(){tail=pool;} //初始化KDTree
Node* Build(Point *a,int l,int r,int div) //建树
{
if(l>=r) return NULL;
Node *p=tail++;
p->div=div;
int mid=(l+r)/;
nth_element(a+l,a+mid,a+r,cmpx(div));
p->e=a[mid];
p->lc=Build(a,l,mid,(div+)%K);
p->rc=Build(a,mid+,r,(div+)%K);
return p;
} struct Qnode
{
Point p;
double dist;
Qnode(){}
Qnode(Point _p,double _dist){p=_p; dist=_dist;}
bool operator <(const Qnode &oth)const{return dist<oth.dist;}
};
priority_queue<Qnode> Q;
void Search(const Point &p,Node *now,int div,int m) //在now节点子树下搜索p点的m近邻
{
if(now==NULL) return;
if(cmp(p,now->e,div))
{
Search(p,now->lc,(div+)%K,m);
if(Q.size()<m)
{
if(now->e.c <= p.c) Q.push(Qnode(now->e,p.distance(now->e)));
Search(p,now->rc,(div+)%K,m);
}
else
{
if(p.distance(now->e) < Q.top().dist || (p.distance(now->e) == Q.top().dist && now->e.idx < Q.top().p.idx))
{
if(now->e.c <= p.c)
{
Q.pop();
Q.push(Qnode(now->e,p.distance(now->e)));
}
}
if(sqr((now->e.x[div])-(p.x[div])) < Q.top().dist) Search(p,now->rc,(div+)%K,m);
}
}
else
{
Search(p,now->rc,(div+)%K,m);
if(Q.size()<m)
{
if(now->e.c <= p.c) Q.push(Qnode(now->e,p.distance(now->e)));
Search(p,now->lc,(div+)%K,m);
}
else
{
if(p.distance(now->e) < Q.top().dist || (p.distance(now->e) == Q.top().dist && now->e.idx < Q.top().p.idx))
{
if(now->e.c <= p.c)
{
Q.pop();
Q.push(Qnode(now->e,p.distance(now->e)));
}
}
if(sqr((now->e.x[div])-(p.x[div])) < Q.top().dist) Search(p,now->lc,(div+)%K,m);
}
}
} void Search(const Point &p,int m) //搜索p点的m近邻
{
while(!Q.empty()) Q.pop();
Search(p,root,,m);
}
}; int n,m;
KDTree::Point p[maxn]; int main()
{
KDTree::K=;
int T;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++) p[i].input(i);
KDTree::init();
KDTree::root=KDTree::Build(p,,n,); KDTree::Point o;
for(int i=;i<=m;i++)
{
o.input(i);
KDTree::Search(o,);
o=KDTree::Q.top().p;
o.output();
}
}
}
PS.由于只需要最近邻,所以其实并不需要那个优先队列,只不过懒得改了。
HDU 5992/nowcoder 207K - Finding Hotels - [KDTree]的更多相关文章
- hdu-5992 Finding Hotels(kd-tree)
题目链接: Finding Hotels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/ ...
- Hdu-5992 2016ACM/ICPC亚洲区青岛站 K.Finding Hotels KDtree
题面 题意:二维平面上有很多点,每个点有个权值,现在给你一个点(很多组),权值v,让你找到权值小于等于v的点中离这个点最近的,相同的输出id小的 题解:很裸的KDtree,但是查询的时候有2个小限制, ...
- Finding Hotels
Finding Hotels http://acm.hdu.edu.cn/showproblem.php?pid=5992 Time Limit: 2000/1000 MS (Java/Others) ...
- HDU5992 - Finding Hotels
原题链接 Description 给出个二维平面上的点,每个点有权值.次询问,求所有权值小于等于的点中,距离坐标的欧几里得距离最小的点.如果有多个满足条件的点,输出最靠前的一个. Solution 拿 ...
- 【22.95%】【hdu 5992】Finding Hotels
Problem Description There are N hotels all over the world. Each hotel has a location and a price. M ...
- HDU 5992 Finding Hotels(KD树)题解
题意:n家旅店,每个旅店都有坐标x,y,每晚价钱z,m个客人,坐标x,y,钱c,问你每个客人最近且能住进去(非花最少钱)的旅店,一样近的选排名靠前的. 思路:KD树模板题 代码: #include&l ...
- 【kd-tree】hdu5992 Finding Hotels
比较裸的kd-tree,但是比较考验剪枝. 貌似除了经典的矩形距离剪枝之外, 还必须加个剪枝是某个矩形内的最小价格如果大于价格限制的话,则剪枝. #include<cstdio> #inc ...
- HDU 5992 kd-tree
还记得青岛的时候和蕾姐讨论了近三个小时也不知道这是什么东西 后来发现是kdtree 于是拖到寒假才补这个算法 写完几道模板题发现多维的kdtree查找最近也是很简单的拓展 于是很快1A了这道题 它真的 ...
- 2016 ICPC青岛站---k题 Finding Hotels(K-D树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5992 Problem Description There are N hotels all over ...
随机推荐
- Main.storyboard: WKWebView before iOS 11.0 (NSCoding support was broken in previous versions)
在工程里用 故事板写了 wkwebview 如果运行在 ios11以下 就会报这个错误,如果要支持iOS 11 以下的用户,请重写View部分,使用代码调用WKWebView,而不用使用故事版来加 ...
- OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法
1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...
- mysql 5.7中的threads
>desc threads; +---------------------+---------------------+------+-----+---------+-------+ | Fie ...
- [Android]Android数据的四种存储方式
存储方式 Android提供以下四种存储方式: SharePreference SQLite File ContentProvider Android系统中数据基本都是私有的,一般存放在“data/d ...
- 15款css3鼠标悬停图片动画过渡特效
分享15款css3鼠标悬停图片动画过渡特效.这是一款15款不同效果的css3 hover动画过渡效果代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class ...
- Linux 常用命令随笔(二)
Linux 常用命令随笔(二) 1.RPM RPM是RedHat Package Manager(RedHat软件包管理工具) 1.1.安装软件包 rpm -ivh ***.rpm 其中i表示安装,v ...
- 【九天教您南方cass 9.1】 08 绘制等高线及对其处理
同学们大家好,欢迎收看由老王测量上班记出品的cass9.1视频课程 我是本节课主讲老师九天. 我们讲课的教程附件也是共享的,请注意索取测量空间中. [点击索取cass教程]5元立得 (给客服说暗号:“ ...
- WebMisSharp更新了,最新版本1.5.2,WebMisCentral-Client最新版
WebMisSharp更新记录 Version 1.5.2 1.5.2下载地址:http://item.taobao.com/item.htm?spm=686.1000925.1000774.13.w ...
- Linux(C/C++)下的文件操作open、fopen与freopen
open是linux下的底层系统调用函数, fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲. linxu下的fopen是open的封装函数,fopen最终还是要调用底层的 ...
- 在IDEA中将项目部署到Tomcat的方法及两种模式的区别
转自:https://www.jianshu.com/p/fb0ed26c35d5 1.添加tomcat服务器 点右上角编辑配置 编辑配置 点击左上角+选择tomcat服务器 添加tomcat ...