【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 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
Source
2016ACM/ICPC亚洲区青岛站-重现赛(感谢中国石油大学)
【题目链接】:http://acm.split.hdu.edu.cn/showproblem.php?pid=5992
【题解】
先炫耀一下;
kd-tree;
如果没学过kd-tree不建议你再往下看。
这里不能用那个四边形的估价函数;会超时。
有一个更好的估价函数是
judge=(op.d[fx]-t[rt].d[fx])^2;
op是输入的询问,d[2]表示坐标;(二维)
这里的fx是kd-tree中当前这个域的划分依据,fx==0表示是以x轴作为划分依据、fx==1表示是以y轴作为划分依据;
具体点
int zuo = t[rt].l,you = t[rt].r;
if (op.d[fx]>t[rt].d[fx])//先搞fx维坐标离操作坐标近的;
swap(zuo,you);
query(zuo,1-fx);//优先搞"左"子树
bool should = false;//判断要不要搞右子树;
if (dis == INF)//如果距离为正无穷表示还没有更新过答案就要搞
should = true;
else
{
LL ju = sqr(op.d[fx]-t[rt].d[fx]);//否则看看这个划分依据fx的维当前这个fx坐标与操作坐标的距离的平方
//经过了swap "you"子树内全部都是比t[rt].d[fx]小或全都比它大的节点;
if (ju <= dis)//如果估价函数比当前更新到的答案小;那么就要搞右子树
should = true;//如果估价函数比当前更新到的答案还要大,那么就不要搞右子树了;
}//因为如果继续搞右子树,fx这一维的坐标在右子树里面是单调的;ju只会越来越大;
if (should)
query(you,1-fx);
除此之外;还可以在每个树的节点里面储存以这个节点为根的子树下面最低消费最小的min;如果min都大于op.n则可以不用进入子树了;
(交程序的时候选g++不然会莫名TLE);
【完整代码】
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const int MAXN = 205000;
const LL INF = 1e18;
struct point
{
int min, n, dot, l,r;
LL d[2];
};
int n, m, root, now;
LL dis;
point t[MAXN];
point op,ans;
void input_data()
{
scanf("%d%d", &n,&m);
for (int i = 1; i <= n; i++)
{
scanf("%I64d%I64d%d", &t[i].d[0], &t[i].d[1],&t[i].n);
t[i].dot = i;
}
}
bool cmp_1(point a, point b)
{
return a.d[now] < b.d[now];
}
void gengxin(int father, int son)
{
if (t[father].min > t[son].min)
t[father].min = t[son].min;
}
void up_data(int rt)
{
t[rt].min = t[rt].n;
int l = t[rt].l, r = t[rt].r;
if (l) gengxin(rt, l);
if (r) gengxin(rt, r);
}
int build(int begin, int end, int fa,int fx)
{
int m = (begin + end) >> 1;
now = fx;
nth_element(t + begin, t + m, t + end + 1, cmp_1);
if (begin < m)
t[m].l = build(begin, m - 1, m, 1 - fx);
else
t[m].l = 0;
if (m < end)
t[m].r = build(m + 1, end, m, 1 - fx);
else
t[m].r = 0;
up_data(m);
return m;
}
LL sqr(LL x)
{
return x*x;
}
void query(int rt,int fx)
{
if (!rt)
return;
int temp1 = t[rt].min;
if (temp1 > op.n)
return;
if (t[rt].n <= op.n)
{
LL dd = sqr(op.d[0]-t[rt].d[0])+sqr(op.d[1]-t[rt].d[1]);
if (dd < dis || (dd==dis && t[rt].dot < ans.dot))
{
dis = dd;
ans.d[0] = t[rt].d[0];
ans.d[1] = t[rt].d[1];
ans.n = t[rt].n;
ans.dot = t[rt].dot;
}
}
int zuo = t[rt].l,you = t[rt].r;
if (op.d[fx]>t[rt].d[fx])
swap(zuo,you);
query(zuo,1-fx);
bool should = false;
if (dis == INF)
should = true;
else
{
LL ju = sqr(op.d[fx]-t[rt].d[fx]);
if (ju <= dis)
should = true;
}
if (should)
query(you,1-fx);
}
void get_ans()
{
root = build(1, n, 0, 0);
for (int i = 1; i <= m; i++)
{
scanf("%I64d%I64d%d",&op.d[0],&op.d[1],&op.n);
dis = INF;
query(root,0);
printf("%I64d %I64d %d\n",ans.d[0],ans.d[1],ans.n);
}
}
int main()
{
//freopen("F:\\rush.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--)
{
input_data();
get_ans();
}
return 0;
}
【22.95%】【hdu 5992】Finding Hotels的更多相关文章
- 【改革春风吹满地 HDU - 2036 】【计算几何-----利用叉积计算多边形的面积】
利用叉积计算多边形的面积 我们都知道计算三角形的面积时可以用两个邻边对应向量积(叉积)的绝对值的一半表示,那么同样,对于多边形,我们可以以多边形上的一个点为源点,作过该点并且过多边形其他点中的某一个的 ...
- 【HDU 5145】 NPY and girls(组合+莫队)
pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...
- Least Common Multiple (HDU - 1019) 【简单数论】【LCM】【欧几里得辗转相除法】
Least Common Multiple (HDU - 1019) [简单数论][LCM][欧几里得辗转相除法] 标签: 入门讲座题解 数论 题目描述 The least common multip ...
- 七夕节 (HDU - 1215) 【简单数论】【找因数】
七夕节 (HDU - 1215) [简单数论][找因数] 标签: 入门讲座题解 数论 题目描述 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们 ...
- 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...
- 【贪心】【模拟】HDU 5491 The Next (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5491 题目大意: 一个数D(0<=D<231),求比D大的第一个满足:二进制下1个个数在 ...
- 【动态规划】【二分】【最长上升子序列】HDU 5773 The All-purpose Zero
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5773 题目大意: T组数据,n个数(n<=100000),求最长上升子序列长度(0可以替代任何 ...
- 【动态规划】【KMP】HDU 5763 Another Meaning
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...
随机推荐
- CentOS7 NFS配置
如果在安装Centos7时选择安装必要的开发工具选项,所以系统已经安好NFS必要的软件. 配置: # vi /etc/exports /home/qws/share 192.168.168.0/24 ...
- Android实战简易教程-第二十五枪(基于Baas的数据表查询下拉刷新和上拉载入实现!)
上一节我们实现了数据表的载入,可是,当数据表数据非常多时.我们就要考虑数据的分页.这里我们选用了PullToRefreshListView控件,先看一下该控件的说明: 效果图: ...
- Oracle 11gR2光钎链路切换crs服务发生crash
Oracle 11gR2光钎链路切换crs服务发生crash 背景: 我们将Oracle 11gR2(11.2.0.4)在RedHat EnterPrise 5.8上通过RDAC完毕的多路径链路冗余. ...
- 如何创建Hiren的BootCD USB磁盘 -- 制作U盘启动盘
如何创建Hiren的BootCD USB磁盘 原文 https://www.wintips.org/how-to-create-hirens-bootcd-usb-disk/ 本文基本是谷歌翻译 H ...
- linux host主机名配置
1.查看主机名 #hostname 2.查看ip #ifconfig 2.添加主机名配置 #vi /etc/hosts 新增一行 172.23.26.195 vhost145.idmp.safe
- php实现排列组合
php实现排列组合 一.总结 1.回溯:回溯的函数参数有些生疏了,记录递归的位置(pos或step),还要有东西(vis数组)来记录这个是否已经被访问 2.php全局变量的使用 :外部定义的普通变量, ...
- 团队作业-Beta冲刺(1)
这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2 这个作业要求在哪里 https://edu.cnblo ...
- POJ 1012:Joseph
Joseph Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 50068 Accepted: 19020 Descript ...
- Activity启动模式的深入分析
网上关于Activity启动模式的文章许多.可是看起来都千篇一律,看完之后我们都能理解这4种启动模式.只是官方api对singleTask这个启动模式解释有些争议,导致我事实上并没有真正理解这几种模式 ...
- Android学习笔记之Bitmap位图的旋转
位图的旋转也可以借助Matrix或者Canvas来实现. 通过postRotate方法设置旋转角度,然后用createBitmap方法创建一个经过旋转处理的Bitmap对象,最后用drawBitmap ...