pairs
John在X轴上有n个点,它们的坐标是(X [i],0),(i=0,1,2,…,n−1)。他想知道多少对< a,b > ,使得|x[b]−x[a]|≤k。(a<b)
Input
Each test case begins with two integers n,k(1≤n≤100000,1≤k≤109).
Next n lines contain an integer x[i](−109≤x[i]≤109), means the X coordinates.
第一行包含一个整数T(约5),表示案例的数量。
每个测试用例以两个整数n,k开始(1≤n≤100000,1≤k≤109)。
接下来的n行每行包含一个整数x[i](−109≤x[i]≤109),表示x坐标。
Output
对于每种情况,输出一个整数 表示有多少对<a,b> |x[b]−x[a]|≤k。
Sample Input
1.|x[b]−x[a]|≤k.(a<b),去绝对值即 x[a] - k ≤ x[b] ≤ x[a] + k (a<b)。接下来通过式子x[b] ≤ x[a] + k (a<b)来解题
2.对数组x进行排序。
3.遍历数组x,对于每个元素x[i],通过二分查找(upper_bound的使用)在数组x中范围是从i到n的元素中是否存在一个元素x[j],使得|x[i] - x[j]| <= k。如果存在,则将满足条件的元素对数量加1。(ps:x[i]即代表x[a],查找的(x[j])即代表x[b])
4.upper_bound(x+i, x+n, k+x[i])
表示在数组x的范围内从当前元素(x[i])开始查找第一个大于k+x[i]
的元素。(ps:小于等于x[a] + k才是符合条件的x[b],所以我们要找到第一个大于x[a] + k的x[b],以便后面的计算)
5.upper_bound(x+i, x+n, k+x[i]) - x
表示计算 找到的元素 在数组中的位置(ps:下标从0开始)。
6.upper_bound(x+i, x+n, k+x[i]) - x - i - 1
表示计算找到的元素与当前遍历的元素之间的距离(ps:不包括当前元素)。
7.cnt += ...
表示将计算得到的满足条件的元素对数量。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1e8+10;
int T,n,k;
int x[MAXN];
int main()
{
scanf("%d",&T);
while(T--)
{
int cnt=0;
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&x[i]);
}
sort(x,x+n);
for(int i=0;i<n;i++)//x[i]即代表x[a],查找的即代表x[b]
{
cnt+=(upper_bound(x+i,x+n,k+x[i])-x)-i-1;
}
printf("%d\n",cnt);
}
return 0;
}