思路:如果没有限制 k 种数字的话,直接比较最长的连续的数字串(前后要么相等,要么相差 1)即可
限制了 k 种数字,我们只需要多添加一步,开一个二维数组,第一维存储一串连续的数字,第二维存储每个连续数字的个数
eg:1 1 2 3 7 7 8 8 9 ---> a[0] = 2 1 1, a[1] = 2 2 1
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
using namespace std;
int T;
void solve()
{
int n, k;
cin >> n >> k;
map<int, int> p;
for (int i = 0; i < n; i ++ )
{
int x;
cin >> x;
p[x] ++ ;
}
vector<vector<int>> a(n + 1);
int idx = -1, last = -1;
for (auto t : p)
{
// 移到下一个坑位
if (last + 1 != t.first)
{
idx ++ ;
// 为前缀和做准备
a[idx].push_back(0);
a[idx].push_back(t.second);
}
// 在原来的坑位上尾加法
else a[idx].push_back(t.second);
last = t.first;
}
int ans = 0;
for (auto t : a)
{
// 退出循环
if (t.size() == 0) break;
// 这里的 sz 包括了 添加的0元素
int sz = t.size() - 1;
for (int i = 1; i <= sz; i ++ ) t[i] += t[i - 1];
if (k >= sz)
{
ans = max(ans, t[sz]);
continue;
}
// 从0开始,保证了 前缀和 包括 第一个元素
for (int i = 0; i + k <= sz; i ++ )
ans = max(ans, t[i + k] - t[i]);
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T -- )
{
solve();
}
return 0;
}