【bzoj1941】[Sdoi2010]Hide and Seek KD-tree
题目描述
小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏。 但是,他们觉得,玩普通的捉迷藏没什么意思,还是不够寂寞,于是,他们决定玩寂寞无比的螃蟹版捉迷藏,顾名思义,就是说他们在玩游戏的时候只能沿水平或垂直方向走。一番寂寞的剪刀石头布后,他们决定iPig去捉giPi。由于他们都很熟悉PKU的地形了,所以giPi只会躲在PKU内n个隐秘地点,显然iPig也只会在那n个地点内找giPi。游戏一开始,他们选定一个地点,iPig保持不动,然后giPi用30秒的时间逃离现场(显然,giPi不会呆在原地)。然后iPig会随机地去找giPi,直到找到为止。由于iPig很懒,所以他到总是走最短的路径,而且,他选择起始点不是随便选的,他想找一个地点,使得该地点到最远的地点和最近的地点的距离差最小。iPig现在想知道这个距离差最小是多少。 由于iPig现在手上没有电脑,所以不能编程解决这个如此简单的问题,所以他马上打了个电话,要求你帮他解决这个问题。iPig告诉了你PKU的n个隐秘地点的坐标,请你编程求出iPig的问题。
输入
第一行输入一个整数N 第2~N+1行,每行两个整数X,Y,表示第i个地点的坐标
输出
一个整数,为距离差的最小值。
样例输入
4
0 0
1 0
0 1
1 1
样例输出
1
题解
KD-tree
如果我们已经知道了一个固定的点,那么很容易求出距离它最远和最近的点。
于是我们可以枚举已知的点,使用KD-tree求出与一个点距离最近和最远(好像可以贪心)的点。
其中求最远的估价函数和最近点稍有区别,自己yy一下就好。
注意求最近点时要忽略相同的点。
#include <cstdio>
#include <algorithm>
#define N 1000010
#define inf 0x7fffffff
using namespace std;
struct data
{
int p[2] , minn[2] , maxn[2] , c[2];
}a[N];
int d , root , ans;
bool cmp(data a , data b)
{
return a.p[d] == b.p[d] ? a.p[d ^ 1] < b.p[d ^ 1] : a.p[d] < b.p[d];
}
void pushup(int k , int s)
{
a[k].minn[0] = min(a[k].minn[0] , a[s].minn[0]);
a[k].minn[1] = min(a[k].minn[1] , a[s].minn[1]);
a[k].maxn[0] = max(a[k].maxn[0] , a[s].maxn[0]);
a[k].maxn[1] = max(a[k].maxn[1] , a[s].maxn[1]);
}
int build(int l , int r , int now)
{
int mid = (l + r) >> 1;
d = now , nth_element(a + l , a + mid , a + r + 1 , cmp);
a[mid].minn[0] = a[mid].maxn[0] = a[mid].p[0];
a[mid].minn[1] = a[mid].maxn[1] = a[mid].p[1];
if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1) , pushup(mid , a[mid].c[0]);
if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1) , pushup(mid , a[mid].c[1]);
return mid;
}
int getmin(int k , int x)
{
int ret = 0;
if(a[x].p[0] < a[k].minn[0]) ret += a[k].minn[0] - a[x].p[0];
if(a[x].p[0] > a[k].maxn[0]) ret += a[x].p[0] - a[k].maxn[0];
if(a[x].p[1] < a[k].minn[1]) ret += a[k].minn[1] - a[x].p[1];
if(a[x].p[1] > a[k].maxn[1]) ret += a[x].p[1] - a[k].maxn[1];
return ret;
}
int getmax(int k , int x)
{
return max(abs(a[k].maxn[0] - a[x].p[0]) , abs(a[k].minn[0] - a[x].p[0])) + max(abs(a[k].maxn[1] - a[x].p[1]) , abs(a[k].minn[1] - a[x].p[1]));
}
void querymin(int k , int x)
{
int dn = abs(a[k].p[0] - a[x].p[0]) + abs(a[k].p[1] - a[x].p[1]) , dl = inf , dr = inf;
if(dn && dn < ans) ans = dn;
if(a[k].c[0]) dl = getmin(a[k].c[0] , x);
if(a[k].c[1]) dr = getmin(a[k].c[1] , x);
if(dl < dr)
{
if(dl < ans) querymin(a[k].c[0] , x);
if(dr < ans) querymin(a[k].c[1] , x);
}
else
{
if(dr < ans) querymin(a[k].c[1] , x);
if(dl < ans) querymin(a[k].c[0] , x);
}
}
void querymax(int k , int x)
{
int dn = abs(a[k].p[0] - a[x].p[0]) + abs(a[k].p[1] - a[x].p[1]) , dl = 0 , dr = 0;
if(dn > ans) ans = dn;
if(a[k].c[0]) dl = getmax(a[k].c[0] , x);
if(a[k].c[1]) dr = getmax(a[k].c[1] , x);
if(dl > dr)
{
if(dl > ans) querymax(a[k].c[0] , x);
if(dr > ans) querymax(a[k].c[1] , x);
}
else
{
if(dr > ans) querymax(a[k].c[1] , x);
if(dl > ans) querymax(a[k].c[0] , x);
}
}
int main()
{
int n , ret = inf , tmp , i;
scanf("%d" , &n);
for(i = 1 ; i <= n ; i ++ ) scanf("%d%d" , &a[i].p[0] , &a[i].p[1]);
root = build(1 , n , 0);
for(i = 1 ; i <= n ; i ++ )
ans = inf , querymin(root , i) , tmp = ans , ans = 0 , querymax(root , i) , ret = min(ret , ans - tmp);
printf("%d\n" , ret);
return 0;
}
【bzoj1941】[Sdoi2010]Hide and Seek KD-tree的更多相关文章
- 【BZOJ1941】[Sdoi2010]Hide and Seek KDtree
[BZOJ1941][Sdoi2010]Hide and Seek Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了 ...
- 【bzoj1941】 Sdoi2010—Hide and Seek
http://www.lydsy.com/JudgeOnline/problem.php?id=1941 (题目链接) 题意 给出n个二维平面上的点,求一点使到最远点的距离-最近点的距离最小. Sol ...
- 【bzoj1941】[Sdoi2010]Hide and Seek(kd-tree)
bzoj 题意: 给出\(n\)个点,对于每个点,\(d_i\)等于距离其最远的点的距离减去距离最近的点的距离.这里的距离为曼哈顿距离. 求\(min\{d_i\}\). 思路: 考虑直接对每个点暴力 ...
- BZOJ1941:[SDOI2010]Hide and Seek(K-D Tree)
Description 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏- ...
- BZOJ 1941: [Sdoi2010]Hide and Seek(k-d Tree)
Time Limit: 16 Sec Memory Limit: 162 MBSubmit: 1712 Solved: 932[Submit][Status][Discuss] Descripti ...
- 【BZOJ1941】Hide and Seek(KD-Tree)
[BZOJ1941]Hide and Seek(KD-Tree) 题面 BZOJ 洛谷 题解 \(KD-Tree\)对于每个点搜一下最近点和最远点就好了 #include<iostream> ...
- 【BZOJ-1941】Hide and Seek KD-Tree
1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec Memory Limit: 162 MBSubmit: 830 Solved: 455[Submi ...
- [BZOJ1941][Sdoi2010]Hide and Seek
[BZOJ1941][Sdoi2010]Hide and Seek 试题描述 小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他 ...
- bzoj:1941: [Sdoi2010]Hide and Seek
1941: [Sdoi2010]Hide and Seek Time Limit: 16 Sec Memory Limit: 162 MBSubmit: 531 Solved: 295[Submi ...
随机推荐
- 日常-acm-三位数反转
输入一个三位数,分理出它的百位,十位和个位,反转后输出. 样例输入: 127 样例输出: 721 tips:注意最后一位为0的情况,如360,输出063 #include <iostream&g ...
- pycharm创建工程的两种形式:virtualenv环境和系统默认编译器
转自:http://swiftlet.net/archives/3151 pycharm创建工程的时候可以选择编译器,如下图所示: 上图表示创建工程有两种方式:第一种是利用:virtualenv,第二 ...
- mini_batch GD
工作过程:训练总样本个数是固定的,batch_size大小也是固定的,但组成一个mini_batch的样本可以从总样本中随机选择.将mini_batch中每个样本都经过前向传播和反向传播,求出每个样本 ...
- Word2vec资料
Word2vec 很好的资料 Word2Vec-知其然知其所以然 https://www.zybuluo.com/Dounm/note/591752 Word2Vec数学原理讲解 http://w ...
- PAT (Basic Level) Practise (中文)- 1013. 数素数 (20)
http://www.patest.cn/contests/pat-b-practise/1013 令Pi表示第i个素数.现任给两个正整数M <= N <= 104,请输出PM到PN的所有 ...
- 用户价值模型 CITE :https://www.jianshu.com/p/34199b13ffbc
RFM用户价值模型的原理和应用 ▌定义 在众多的用户价值分析模型中,RFM模型是被广泛被应用的:RFM模型是衡量客户价值和客户创利能力的重要工具和手段,在RFM模式中,R(Recency)表示客户购 ...
- (72)zabbix监控日志文件 MySQL日志为例
一般情况下,日志最先反映出应用当前的问题,在海量日志里面找到我们异常记录,然后记录下来,并且根据情况报警,大家可以监控系统日志.nginx.Apache.业务日志. 这边我拿常见的MySQL日志做监控 ...
- APP客户端图片上传PHP接口
1.客户端 file_get_contents($_FILES['img']['tmp_name']) //获取临时目录下的上传文件流,加密传给接口 2.接口处理端 $img = file_get ...
- AD采样求平均STM32实现
iADC_read(, &u16NTC_1_Sample_Val_ARR[]); == ui8FirstSampleFlag) { ; i<; i++) { u16NTC_1_Sampl ...
- ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph(有源上下界最大流 模板)
关于有源上下界最大流: https://blog.csdn.net/regina8023/article/details/45815023 #include<cstdio> #includ ...