1. 题目来源
链接:P1102 A-B 数对
2. 题目解析
水题,题目不难,但是答案记得开 long long...............
,要不一直 WA
一个点。这种求个数、求方案、且限制条件不够强的题目,一定要考虑最终的方案数是否很大。
题解区发现一位大佬使用双指针来做,也很不错,贴一下大佬的思路~
我在考虑能不能直接采用 lower_bound()、upper_bound()
代替这两个 while()
…但貌似必然没有双指针的效果好,常数可能很大…甚至是 O(n)
。
代码:
// https://www.luogu.com.cn/problem/P1102
#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;
const int N = 2e5 + 5;
int n, c;
int a[N];
unordered_map<int, int> h;
int main() {
scanf("%d%d", &n, &c);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]), h[a[i] - c] ++ ;
long long res = 0;
for (int i = 0; i < n; i ++ )
if (h.count(a[i])) // 不加这个也行,但哈希表会插入很多无效值
res += h[a[i]];
printf("%lld\n", res);
return 0;
}
双指针大佬:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 10;
int n , c;
int a[N];
int main ()
{
cin >> n >> c;
for(int i = 1 ; i <= n ; i ++) cin >> a[i];
sort(a + 1 , a + 1 + n);
int l = 1, r1 = 1 , r2 = 1;
ll ans = 0;
for(l = 1 ; l <= n ; l ++) {
while(r1 <= n && a[r1] - a[l] <= c) r1 ++;
while(r2 <= n && a[r2] - a[l] < c ) r2 ++;
if(a[r2] - a[l] == c && a[r1 - 1] - a[l] == c && r1 - 1 >= 1)
ans += r1 - r2;
}
cout << ans;
return 0;
}