pairs
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 189 Accepted Submission(s): 88
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
题意:
知道n个点的很坐标x[i],求有多少对点的距离小于等于k
思路和注意点:
1、元素从小到大排序
2、遍历一遍元素,对每个元素x[a],找到第一个元素x[b],使得x[b]-x[a]>k,则对于点x[a]来说,有b-a-1对,累加至最后即为答案
3、答案要用__int64,因为可能对每个x[a],后面所有数都满足条件,n<=100000,那么最多就有(100000+1)*100000/2,超过了int范围。。。
4、找第一个元素x[b]要用二分搜索,从x+1到n-1,找。。。否则会超时。。。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL __int64
int BiSearch(int *num,int n,int k,int x)
{
int left=x+1,right=n-1;
while(left<=right)
{
int mid=(left+right)>>1;
if(num[mid]-num[x]<=k)
left=mid+1;
else if(num[mid]-num[x]>k)
right=mid-1;
}
return left-x-1;
}
int main()
{
freopen("1.in","r",stdin);
// freopen("1.out","w",stdout);
int T;
int n,k;
int num[100100];
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
memset(num,0,sizeof(num));
for(int i=0;i<n;i++)
scanf("%d",num+i);
sort(num,num+n);
LL ans=0;
for(int i=0;i<n;i++)
{
ans+=BiSearch(num,n,k,i);
}
printf("%I64d\n",ans);
}
return 0;
}
另一种方法:http://www.cnblogs.com/lzj-0218/p/4306275.html