hdu5178 pairs 二分

pairs

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4207    Accepted Submission(s): 1504


 

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.  

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

思路: 

把数组降序排序,这样我们从数组的第一个开始往后找就可以去掉绝对值符号了,对于每个xb,temp = xb - k < xa,只要二分找到恰好小于xa的那个temp,那么temp之前一直到xa的数就一定符合条件;

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<cmath>
#define ll long long
#define pi acos(-1)
using namespace std;
int num[100005];
bool cmp(int x,int y)
{
    return x > y;
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t --)
    {
        ll ans = 0;
        int n,k;
        scanf("%d %d",&n,&k);
        for (int i = 0;i < n;i ++)
            scanf("%d",&num[i]);
        sort(num,num + n,cmp);
        for (int i = 0;i < n - 1;i ++)
        {
            int temp = num[i] - k,mid;
            int l = i + 1,r = n - 1;
            while (l <= r)
            {
                mid = (l + r) / 2;
                if (num[mid] >= temp)
                    l = mid + 1;
                else
                    r = mid - 1;
            }
            ans += l - i - 1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/cloudy_happy/article/details/81265604