pairs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 320 Accepted Submission(s): 143
Problem Description
John has
n
points on the X axis, and their coordinates are
(x[i],0),(i=0,1,2,…,n−1)
. He wants to know how many pairs
<a,b>
that
|x[b]−x[a]|≤k.(a<b)
Input
The first line contains a single integer
T
(about 5), indicating the number of cases.
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.
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.
Output
For each case, output an integer means how many pairs
<a,b>
that
|x[b]−x[a]|≤k
.
Sample Input
2 5 5 -100 0 100 101 102 5 300 -100 0 100 101 102
Sample Output
3 10
Source
真的是很久很久没有用到二分查找了,真的是没想到,想了半天都没想到这个。。。。
这里我们需要注意的一点是,数据比较大,要用long long,不能用int。
我们遍历每一个a[i].然后找到位子极限位子r,使得r-i个a都能满足这个条件,然后依次相加得出答案。这里我们直接上代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long int
ll a[100005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ll n,k;
scanf("%I64d%I64d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%I64d",&a[i]);
}
sort(a,a+n);
ll output=0;
for(int i=0;i<n;i++)//依次遍历每一个a【i】,找到他们的极限位子r
{
int l=i+1;
int r=n-1;
int mid=(l+r)/2;
while(l<=r)
{
mid=(l+r)/2;
if(a[mid]-a[i]>k)//如果中间位子的a【mid】-a【i】>k明显我们要找的位子要在mid左边,所以我们这里让r=mid-1就行了
r=mid-1;
else
l=mid+1;//这里同理
}
output+=r-i;
//printf("%d\n",r);
}
printf("%I64d\n",output);
}
}