目录
牛客小白月赛24 B组队
题目描述
你的团队中有 nnn 个人,每个人有一个能力值 aia_iai,现在需要选择若干个人组成一个团队去参加比赛,由于比赛的规则限制,一个团队里面任意两个人能力的差值必须要小于等于 kkk ,为了让更多的人有参加比赛的机会,你最多能选择多少个人参加比赛?
输入描述:
第一行一个整数 TTT,表示案例组数。
每个案例有两行:
第一行两个正整数 n,kn,kn,k ,表示人的数量。
第二行n个以空格分隔的整数 aia_iai ,表示每个人的能力值。
输出描述:
每个案例输出一行,表示可以参加比赛的最多人数。
示例1
输入
1 5 3 8 3 5 1 6
输出
3
说明
选择能力值为 3,5,63,5,63,5,6 或者 5,6,85,6,85,6,8
备注:
T ≤1 0
1 ≤ n ≤ 2e5 1 ≤ k ≤ 1e9
1 <= a[i] <= 1e9
解题思路:
首先思考题目要我们求最大的人数,这个答案具有单调性的(人数越少越容易满足<=k的条件),所以这题是典型的二分答案前缀模型
首先将所有人的能力存入数组后从小到大进行排序,写一个二分答案前缀模型,然后判断函数内通过滑动窗口来判断是否满足<=k,如果满足就不需要再往后进行判断直接返回 真,否则判断完都没有返回 真,此时就代表不成立,返回 假,因为是前缀模型,最终输出 R
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5 + 5;
int n, k;
int a[maxn];
bool ok(int mid)
{
//滑动窗口判断最大值减去最小值是否满足<=k,如果满足了就代表不需要判断后面的了,因为题目只求长度
for(int i = 1; i + mid - 1 <= n; i++)
{
if(a[i + mid - 1] - a[i] <= k)
{
return true;
}
}
return false;
}
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n >> k;
for(int i = 1; i <= n; i++)cin >> a[i];
//将所有人的能力值从小到大排序
sort(a + 1, a + n + 1);
int l = 1, r = n;
//二分答案前缀模型
while(l <= r)
{
int mid = (l + r) >> 1;
if(ok(mid))l = mid + 1;
else r = mid - 1;
}
cout << r << endl;
}
return 0;
}