Problem Description
During a programming contest, teams cannot sit close to each other, because then a team might copy the solution of another team. You are given the locations of the teams and the minimum required Euclidian distance between two teams. You have to find the number of pairs of teams that sit too close to each other.
 
Input
On the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case:
One line with two integers n (1 <= n <= 100 000) and d (1 <= d <= 50): the number of teams and the minimum distance between two teams.
n lines with two integers xi (0 <= xi <= 1 000 000 000) and yi (0 <= yi <= 1 000 000 000): the coordinates of the i-th team. No two teams will have the same coordinates.
 
Output
For each test case:
One line with the number of pairs of teams that sit too close to each other.

题目大意:给平面上n个点,问有多少对点间的距离小于d。

思路:一眼可以看到,虽然x轴和y轴的范围很大,但是d却很小,这应该是一个突破口。

那么这个d怎么利用呢。思考一下,对于任意一个点P,和它的距离小于d的点,至少应该在一个以P为中心的2d*2d的正方形中。

因为要题目要求的是对数,那么我们可以只考虑P点的右半部分的点(因为左边部分的点与P的组合在计算左边的点的时候已经算了)。

那么,我们就是要考虑,对于点P(x0, y0),只考虑x = x0、x0+1、……、x0+d-1的点。

穷举这些x = x0 + i,那么y轴的范围就应该在[y0 - t, y0 + t]之间,其中 t 是满足i^2 + t^2 < d^2的最大整数(注意题目都是整点)。

如果对于每一个x = x0 + i的点我们都可以收集起来,按y轴排好,那么二分查找,可以得到 结果 = 小于等于y0 + t的数目 - 小于y0 - t的数目。

因为x的范围很大,不可能说每个点开个数组,我们可以用C++的map存起来,每个有可能的x开一个vector,然后排序即可(注意找map中是否存在x的时候最好用map.find(x),直接用map[x]会创建一个x留在map中,可能导致效率的减缓)。

如果不用map也不是不可以,只要把点都从小到大(x轴为第一关键字,y轴第二关键字)排好序,每次需要哪个x的时候二分查找也是可以的。

我们好像还没算x轴相同的呢。对于x轴相同的,弄俩指针,从前往后扫就可以统计出来了,这个还是不难的。

细节可以看代码,时间复杂度为O(n*d*log(n))。

代码(14109MS):

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
typedef long long LL; const int MAXN = ; int T, n, d, x, y;
map<int, vector<int> > mymap; LL solve() {
LL ans = ;
for(map<int, vector<int> >::iterator it = mymap.begin(); it != mymap.end(); ++it) {
sort(it->second.begin(), it->second.end());
for(int i = , j = , n = it->second.size(); i < n; ++i) {
while(j < n && it->second[i] + d > it->second[j]) ++j;
ans += j - i - ;
}
}
int d2 = d * d;
for(map<int, vector<int> >::iterator it = mymap.begin(); it != mymap.end(); ++it) {
for(vector<int>::iterator p = it->second.begin(); p != it->second.end(); ++p) {
for(int i = , t = d; i < d; ++i) {
while(i * i + t * t >= d2) --t;
map<int, vector<int> >::iterator nx = mymap.find(it->first + i);
if(nx != mymap.end()) {
ans += (upper_bound(nx->second.begin(), nx->second.end(), *p + t) - nx->second.begin()) -
(lower_bound(nx->second.begin(), nx->second.end(), *p - t) - nx->second.begin());
}
}
}
}
return ans;
} int main() {
scanf("%d", &T);
while(T--) {
mymap.clear();
scanf("%d%d", &n, &d);
for(int i = ; i < n; ++i) {
scanf("%d%d", &x, &y);
mymap[x].push_back(y);
}
printf("%I64d\n", solve());
}
}

HDU 2366 Space(二分计数)的更多相关文章

  1. hdu 2962 Trucking (二分+最短路Spfa)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 Trucking Time Limit: 20000/10000 MS (Java/Others ...

  2. UVA 10816 + HDU 1839 Dijstra + 二分 (待研究)

    UVA 题意:两个绿洲之间是沙漠,沙漠的温度不同,告诉起点,终点,求使得从起点到终点的最高温度最小的路径,如果有多条,输出长度最短的路径: 思路:用最小费用(最短路径)最大流(最小温度)也能搞吧,但因 ...

  3. hdu 2413(最大匹配+二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2413 思路:由于要求最少的时间,可以考虑二分,然后就是满足在limit时间下,如果地球战舰数目比外星战 ...

  4. HDU 5884 Sort (二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5884 nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的 ...

  5. hdu 1281棋盘游戏(二分匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281   Problem Description 小希和Gardon在玩一个游戏:对一个N*M的棋盘, ...

  6. HDU 1025 DP + 二分

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1025 求最长递增子序列,O(n^2)的复杂度超时,需要优化为O(n*logn) f[i]存储长度为i的最小 ...

  7. hdu 2289 要二分的杯子

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2289 大意是 一个Cup,圆台形,给你它的顶部圆的半径,底部圆的半径,杯子的高度,和此时里面装的水的体 ...

  8. HDU 1025 LIS二分优化

    题目链接: acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: ...

  9. HDU 5200 Trees 二分

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5200 bc(中文):http://bestcoder.hdu.edu.cn/contests ...

随机推荐

  1. fatal error C1189: #error : WINDOWS.H already included. MFC apps must not #include <windows.h>

    给对话框添加类, 报错 CalibrateMFCDlg.h(6) : error C2504: “CDialog”: 未定义基类 等多个错误 加上 #include "afxwin.h&qu ...

  2. xftp的使用

    1.xftp 一个基于 MS windows 平台的功能强大的SFTP.FTP 文件传输软件 2.下载安装 *3.在linux上安装服务 sudo yum install vsftp

  3. 在Windows上一键编译各种版本的Protobuf

    所需工具 : cmake  for  windows 和  git for windows 原理:protobuf 是google的一个开源项目,其源代码在github上可以下载到,并且源码都采用cm ...

  4. C# 判断字符串是否为日期格式

    判断字符串内容是否为日期格式,并返回一个日期变量 string str; DateTime dtTime; if (DateTime.TryParse(str, out dtTime)) { //st ...

  5. zepto源码--init--学习笔记

    先展示init函数,由于笔记本屏幕太小,删掉了部分源码注释,才能在一屏内截图. 当我们调用$()的时候,便会直接调用zepto.init()生成zepto对象,跟jquery生成jquery对象类似. ...

  6. 强调语气<strong>和<em>标签,文字设置单独样式<span>

    区别:1,<em> 表示强调,<strong> 表示更强烈的强调. 2,并且在浏览器中<em> 默认用斜体表示,<strong> 用粗体表示. 3,两个 ...

  7. 各个JSON技术的比较

    JSON技术的调研报告 一 .各个JSON技术的简介和优劣1.json-libjson-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,包括com ...

  8. House Building---hdu5538(求表面积水题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5538 题意:有一个三维的图形,先给出平面图是n*m的矩形,每个位置都有不同个数的方块,a[i][j]代 ...

  9. AspectJ本质剖析

    AOP一共有两种方式,spring默认使用的是动态代理(JDK自带的动态代理或者使用cglib的动态代理)和静态代理(ASPECTJ) http://blog.csdn.net/zhao9tian/a ...

  10. Linux绑定双网卡

    Linux绑定双网卡 1. 配置参数文件 版本在centos6以下在/etc/modproe.conf文件中配置,版本是centos6.x或以上在/etc/modproe.d/目录下配置. 2.    ...