HDU5992 - Finding Hotels
Description
给出n(n≤2×105)个二维平面上的点,每个点有权值c。m(m≤2×104)次询问,求所有权值小于等于c的点中,距离坐标(x,y)的欧几里得距离最小的点。如果有多个满足条件的点,输出最靠前的一个。
Solution
拿k-d树搞一搞就好啦。
如果一个子树代表的区域中所有点的权值都大于c,或者到所有点的距离都大于当前答案,就跳过不做。
Code
//Finding Hotels
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline char gc()
{
static char now[1<<16],*S,*T;
if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
return *S++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
typedef long long lint;
int const N=2e5+10;
lint const INF=1LL<<62;
int n,m;
int rt,ch[N][2];
struct point{lint c[3]; int id;} pt[N];
struct zone{lint c1[3],c2[3];} zn[N];
int D; bool cmpPt(point x,point y) {return x.c[D]<y.c[D];}
void create(int p)
{
for(int k=0;k<3;k++) zn[p].c1[k]=zn[p].c2[k]=pt[p].c[k];
ch[p][0]=ch[p][1]=0;
}
void update(int p)
{
for(int k=0;k<3;k++)
zn[p].c1[k]=min(pt[p].c[k],min(zn[ch[p][0]].c1[k],zn[ch[p][1]].c1[k])),
zn[p].c2[k]=max(pt[p].c[k],max(zn[ch[p][0]].c2[k],zn[ch[p][1]].c2[k]));
}
void build(int &p,int L,int R,int k0)
{
p=L+R>>1; create(p);
if(k0==3) k0=0; D=k0;
nth_element(pt+L,pt+p,pt+R+1,cmpPt);
if(L<p) build(ch[p][0],L,p-1,k0+1);
if(p<R) build(ch[p][1],p+1,R,k0+1);
update(p);
}
point A; int r; lint rDst;
lint dst(point B)
{
if(B.c[2]>A.c[2]) return INF;
return (A.c[0]-B.c[0])*(A.c[0]-B.c[0])+(A.c[1]-B.c[1])*(A.c[1]-B.c[1]);
}
lint dst(zone z)
{
if(z.c1[0]==INF||z.c1[2]>A.c[2]) return INF+1;
lint sum=0;
for(int k=0;k<2;k++)
{
lint d=0;
if(A.c[k]<z.c1[k]) d=z.c1[k]-A.c[k];
else if(z.c2[k]<A.c[k]) d=A.c[k]-z.c2[k];
sum+=d*d;
}
return sum;
}
void query(int p)
{
lint d=dst(pt[p]);
if(d<rDst||(d==rDst&&pt[p].id<pt[r].id)) r=p,rDst=d;
if(dst(zn[ch[p][0]])<=rDst) query(ch[p][0]);
if(dst(zn[ch[p][1]])<=rDst) query(ch[p][1]);
}
int main()
{
int task=read();
for(int k=0;k<3;k++) zn[0].c1[k]=INF,zn[0].c2[k]=-INF;
while(task--)
{
n=read(),m=read();
memset(pt,0,sizeof pt);
for(int i=1;i<=n;i++)
for(int k=0;k<3;k++) pt[i].c[k]=read();
for(int i=1;i<=n;i++) pt[i].id=i;
rt=0; build(rt,1,n,0);
for(int i=1;i<=m;i++)
{
for(int k=0;k<3;k++) A.c[k]=read();
r=0,rDst=INF,query(rt);
printf("%lld %lld %lld\n",pt[r].c[0],pt[r].c[1],pt[r].c[2]);
}
}
return 0;
}
P.S.
要开long long哦。
55行在不合法时返回INF+1,是因为我懒得判断左右子树是否存在而这么写的。由于要求最靠前的点,所以dst()==rDst的时候也要做,但如果dst()由于不合法而返回INF的话,在rDst==INF的时候就会有问题,会去递归并不存在的子树从而出锅。其实先判断一下子树是否存在再做比较好,不容易出锅而且比较清晰。
HDU5992 - Finding Hotels的更多相关文章
- hdu-5992 Finding Hotels(kd-tree)
题目链接: Finding Hotels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/ ...
- 【kd-tree】hdu5992 Finding Hotels
比较裸的kd-tree,但是比较考验剪枝. 貌似除了经典的矩形距离剪枝之外, 还必须加个剪枝是某个矩形内的最小价格如果大于价格限制的话,则剪枝. #include<cstdio> #inc ...
- Finding Hotels
Finding Hotels http://acm.hdu.edu.cn/showproblem.php?pid=5992 Time Limit: 2000/1000 MS (Java/Others) ...
- 【HDU5992】Finding Hotels 【KD树】
题意 给出n个酒店的坐标和价格,然后m个查询,每个查询给出一个人的坐标和能承受的最大价格,然后找出在他价格承受范围以内,距离他最近的宾馆,如果有多个,那么输出第一个 分析 kd树的模板题 #inclu ...
- Hdu-5992 2016ACM/ICPC亚洲区青岛站 K.Finding Hotels KDtree
题面 题意:二维平面上有很多点,每个点有个权值,现在给你一个点(很多组),权值v,让你找到权值小于等于v的点中离这个点最近的,相同的输出id小的 题解:很裸的KDtree,但是查询的时候有2个小限制, ...
- 2016 ICPC青岛站---k题 Finding Hotels(K-D树)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5992 Problem Description There are N hotels all over ...
- HDU 5992/nowcoder 207K - Finding Hotels - [KDTree]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5992 题目链接:https://www.nowcoder.com/acm/contest/207/K ...
- 【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 ...
随机推荐
- linkin大话数据结构--Collection和Iterator
linkin大话数据结构--Collection和Iterator Java 集合就像一种容器,可以把多个对象的引用放入容器中.Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系 ...
- shell第一篇
前两天不停的再看内核相关的内容,了解内核的形成.内核的执行流程.内核的作用,结果是舍近求远. 其实我只是想了解一下shell的工作,shell与内核有关,但并不需要我么真正去做什么,至少对于我这样额初 ...
- mac对比class文件
下载反编译工具 wget https://varaneckas.com/jad/jad158g.mac.intel.zip 设置Beyond Compare 填写编译工具路径
- linux命令读取文件中特定行
1.如果你只想看文件的前5行,可以使用head命令, 如: head -5 /etc/passwd 2.如果你想查看文件的后10行,可以使用tail命令, 如: tail -10 /etc/passw ...
- windows 7 wifi热点配置
自我总结,有什么不足或更好的解决方案,请告知,感激不尽! 目的:闲来无事的童鞋,可以试一试自己配置wifi热点. ps:其实wifi热点配置是系统存在的功能,只不过需要配置. 现在win桌面wifi热 ...
- Win7系统下彻底删除无用服务的方法
win7系统下中有非常多的服务项,用户来满足不同行业用户间的所有需求,系统服务也是执行指定系统功能的程序,许多情况下我们想要运行软件或执行外接设备都无法离开系统服务,但并非所有系统服务都是我们用到的, ...
- DAY11-Java中的类--接上篇
一.用户自定义类 1.写先出一个简单的Employee类作为例子说明. 代码如下: import java.time.LocalDate; /** * 自定义方法练习--测试 这个程序中包含了两个类E ...
- 移动端的弹窗滚动禁止body滚动
前言 最近一个需求是弹窗展示列表,显然是需要一个滚动条的,而滚动到底部就会穿透到body滚动,而阻止默认行为是不行的,这样两个都滑动不了 所以我在点击出现弹窗的时候在body加了以下css让它没有滚动 ...
- 12、SEO工程师指南 - 软件项目角色指南系列文章
第11章 SEO工程师 SEO工程师是一个比较新兴的职位,在实际的项目管理过程中,SEO工程师的地位相对靠后,只有在项目试运行以及运营期间才能体现出SEO工程师的作用.在项目完成之后, ...
- Vigenère 密码
略简单的字符串+模拟. 原题链接:https://www.luogu.org/problem/show?pid=1079#sub 如果你对那个图感到懵逼,那属于正常,但没关系,这个图其实作用不大,我们 ...