HDU 5178 pairs —— 思维 + 二分

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5178


 

pairs

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

Problem Description
John has n points on the X axis, and their coordinates are (x[i],0),(i=0,1,2,,n1). 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(1n100000,1k109).
Next n lines contain an integer x[i](109x[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

 

 



题解:

两个要求:1:b>a   2.abs(x[b]-x[a])<=k。

先对数组进行排序。对于满足上述条件的a、b(ab为排序前的序号)来说。a、b的关系是可以互相转化的:

当abs(x[b]-x[a])<=k 且 b>a时,那这一对a、b固然满足条件。

当abs(x[b]-x[a])<=k 且 a>b时,那a就变成b,b就变成a,所以也满足条件。

综上,只需要找到abs(x[b]-x[a])<=k 的a、b对即可,无所谓ab的大小关系。但是直接这样计算会出现重复,正确的做法是,只取一边,即:x[a]+k或者是 x[a]-k,这样就能避免重复。




代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 #define rep(i,s,t) for(int (i)=(s); (i)<=(t); (i)++)
13 #define ms(a,b) memset((a),(b),sizeof((a)))
14 using namespace std;
15 typedef long long LL;
16 const int INF = 2e9;
17 const LL LNF = 9e18;
18 const double eps = 1e-6;
19 const int mod = 1e9+7;
20 const int maxn = 1e5+10;
21 
22 int n, k;
23 int a[maxn];
24 
25 int sch(int x)
26 {
27     int l = 1, r = n;
28     while(l<=r)
29     {
30         int mid = (l+r)>>1;
31         if(a[mid]<=x)
32             l = mid + 1;
33         else
34             r = mid - 1;
35     }
36     return r;
37 }
38 
39 int main()
40 {
41     int T;
42     scanf("%d",&T);
43     while(T--)
44     {
45         scanf("%d%d",&n,&k);
46         rep(i,1,n)
47             scanf("%d",&a[i]);
48 
49         sort(a+1,a+1+n);
50         LL ans = 0;
51         rep(i,1,n-1)
52         {
53             int p = sch(a[i]+k);
54 //            int p = upper_bound(a+1,a+1+n,a[i]+k) - (a+1);
55             ans += p-i;
56         }
57         printf("%I64d\n",ans);
58     }
59 }
View Code

 

posted on 2017-07-29 21:56  h_z_cong  阅读(194)  评论(0编辑  收藏  举报

导航