HDU 5178 Pairs

pairs

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


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
 

 

Source
 

首先将所给的坐标从大到小排序,则此题转化为:对排序后的新数列,对每个左边的x[a]找到它右边最远的x[b]使得x[b]-x[a]<=k,累计所有的b-a的和即可。

这里要做一个小优化,否则直接暴搜会TLE:

  用一个数组pos[i]记录x[i]右边最远的x[b]的b值,由于x[b]是单调递增的,所以找pos[i+1]时只要将b从pos[i]继续往右找即可。

另外答案结果非常大,应用long long来保存

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     int kase;
10     scanf ("%d", &kase);
11     while (kase--)
12     {
13         int n, k;
14         long long ans = 0;
15         int num[100200], pos[100200];
16         scanf ("%d %d", &n, &k);
17         for (int i = 0; i < n; i++)
18         {
19             scanf ("%d", &num[i]);
20         }
21         sort (num, num + n);
22         for (int i = 0; i < n; i++)
23         {
24             if (i == 0)
25             {
26                 for (int j = i + 1; j <= n; j++)
27                     if ( (j < n && num[j] - num[i] > k) || (j == n))
28                     {
29                         pos[i] = j - 1;
30                         ans += j - i - 1;
31                         break;
32                     }
33             }
34             else
35             {
36                 for (int j = pos[i - 1]; j <= n; j++)
37                     if ( (j < n && num[j] - num[i] > k) || j == n)
38                     {
39                         pos[i] = j - 1;
40                         ans += j - i - 1;
41                         break;
42                     }
43             }
44         }
45         printf ("%I64d\n", ans);
46     }
47     return 0;
48 }
[C++]

 

转载于:https://www.cnblogs.com/lzj-0218/p/4306275.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值