序列游戏
Problem
有一个长度为 \(n\) 的序列 \(a\)。你可以去掉 \(k\) 种权值的数字,使新的序列存在最长的权值相同的区间。
求这个最长区间的长度。
\(1 \le k \le n \le 10^5,1 \le a_i \le 10^9\)
Input
第一行包括两个整数 \(n\)、\(k\),分别表示序列的长度和去掉的权值种类。
接下来 \(n\) 行,每行包括一个整数 \(a_i\),表示序列中的第 \(i\) 个元素。
Output
输出包括一个整数,表示去掉k种元素后,最长的权值相同的区间的长度。
Sample
Input 1
9 1
2
7
3
7
7
3
7
5
7
Output 1
4
Solution
双指针题。
对于右指针 \(r\),我们需要找到在它前面离它最远的符合条件 \(l\)。可以证明,离 \(r\) 越远,就越难符合条件。
用 \(map\) 存下每种数出现的次数,再记录下数的种类数。如果超过限制,移动左指针 \(l\) 即可。
代码:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int kmax = 1e5 + 3;
int n, k;
int a[kmax];
map<int, int> mp;
int c, res;
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1, j = 1; j <= n; j++) {
c += ++mp[a[j]] == 1; // 右指针移动
for (; c > k + 1; i++) { // 超过,移动左指针
c -= --mp[a[i]] == 0;
}
res = max(res, mp[a[j]]); // 记录答案
}
cout << res;
return 0;
}

浙公网安备 33010602011771号