题目地址:
https://www.acwing.com/problem/content/description/784/
小镇沿街分布(可以理解为都在数轴上),有 n n n家银行(位置以数轴的坐标表示,金额表示可以被抢走的金额)。两个绑匪试图分别抢劫一个银行,为了让警方多奔波他们商定选择的两个银行距离不小于 d d d。请问,符合约定的情况下他们能抢到的总金额最大是多少。
输入格式:
输入包含
n
+
1
n+1
n+1行。第一行包含两个整数
n
n
n和
d
d
d,分别表示银行的数量和约定的距离。接下来
n
n
n行,每行包含两个整数
a
a
a和
b
b
b,分别表示坐标和金额。
输出格式:
输出一个数字表示可以获得的最大金额。
数据范围:
1
≤
n
≤
2
×
1
0
5
1≤n≤2×10^5
1≤n≤2×105,
1
≤
d
,
a
,
b
≤
1
0
8
1≤d,a,b≤10^8
1≤d,a,b≤108
注意:数据中保证至少存在两个银行之间的距离不小于
d
d
d。
双指针,枚举第二个位置,再穷举符合条件的第一个位置。在枚举第一个位置的时候可以从左向右枚举,并且不需要回退。代码如下:
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int n, d;
struct P {
int a, b;
} p[N];
int main() {
scanf("%d%d", &n, &d);
for (int i = 1; i <= n; i++) scanf("%d%d", &p[i].a, &p[i].b);
sort(p + 1, p + 1 + n, [](auto& p1, auto& p2) { return p1.a < p2.a; });
int res = 0;
for (int i = 1, j = 0, maxb = 0; i <= n; i++) {
while (p[i].a - p[j + 1].a >= d) maxb = max(maxb, p[++j].b);
// 此时j是使得与a[i]距离小于等于d的最右边的j,要排除j为0的情形,此时j无效
if (j) res = max(res, maxb + p[i].b);
}
printf("%d\n", res);
}
时间复杂度 O ( n log n ) O(n\log n) O(nlogn),空间 O ( 1 ) O(1) O(1)。