1. 问题分析

1.1 问题本质

给定 个点 和一个容差 ,寻找一个基准值 (室内温度),使得落在区间 内的点数量最大化。

1.2 数学转化

不等式 可以转化为: 或者等价地,对于每一个确定的 ,只要 落入区间 ,该队员即可进入状态。 进一步抽象:在数轴上给定 个点,求一个长度为 的闭区间 (其中 ),使其覆盖的点数量最多。

2. 算法策略选择

针对此类“变长窗口覆盖”或“区间点集覆盖”问题,主要有两种主流策略:

方案 A:差分数组与前缀和(空间换时间)

由于 的取值范围 以内,可以将每个队员的需求看作对温度区间 的一次“覆盖贡献”。使用差分数组记录每个区间的起始和结束,最后通过一次扫描前缀和求出覆盖数最大的点。

  • 优点:时间复杂度 ,在 较小时极快。
  • 缺点:若 取值范围极大(如 ),则无法应用;且此题需要处理下标越界(负数温度)。

方案 B:排序 + 双指针(最优算法)

将点集 排序后,利用滑动窗口(双指针)维护一个跨度不超过 的区间。

  • 分析:该方案不依赖于 的取值范围,仅依赖于 的规模。它是解决此类统计覆盖问题的标准范式,具有更好的通用性和内存局部性。
  • 判定:选择 方案 B(排序 + 双指针) 作为主算法。

3. 代码实现

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, p;
    cin >> n >> p;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];

    sort(a.begin(), a.end());

    int l = 0;
    int ans = 0;
    for (int r = 0; r < n; r++) {
        while (l <= r && a[r] - a[l] > p * 2) {
            l++;
        }
        ans = max(ans, r - l + 1);
    }

    cout << ans << endl;
}