题目链接:
题目
“蓝猫淘气三千问,看蓝猫,我有姿势我自豪!”话说能考上的孩纸们肯定都是很有姿势的孩纸们,但是大家普遍偏科,都只有一门科目考得好。已知的入学考试科目数量小于等于,而有个学生参加了入学考试。现在要刷人了,招生办每一次刷人会把一个科目考得好的人全部刷掉,但是最多不能刷超过次。(刷就是不录取)而的校长看录取名单时,最喜欢看的就是连续都是同一个科目考得好的人。他定义完美学生序列为连续且考得好的科目都为同一门的学生序列。现在招生办主任想让你帮他设计一种录取方案,使得最长的完美学生连续子序列尽量长。
输入
共行,第一行个正整数,。表示入学考试人数,表示刷人次数上限。
接下来行,每行仅一个正整数,为号学生所考得好的科目。
输出
仅个正整数,为最长的最长完美学生连续子序列。
样例输入
9 1
2
7
3
7
7
3
7
5
7
样例输出
4
样例解释
总共有个学生,最多只能刷一次学生。
若不刷,最长完美学生连续子序列长度为
若刷掉考第门考得好的学生,则学生序列变成,最长完美学生连续子序列长度为.
数据范围
对于的数据:
对于的数据:
对于的数据:
思路
这道题是一道模拟题吧。
我们就不停的维护一个连续的且数的种类不超过的序列,那么我们把它这个序列中数量少的个踢掉,就只剩一个数量最长的完美学生连续子序列了。
那我们就不停的维护,然后中途不停的找最长完美学生子序列,找到最大的那个,就是答案了。
代码
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
int n, k, a[100001], num[1000007], in[1000007], kind, ans;
queue<int>q;
int get_hash(int x) {//求hash值
int tmp = x % 1000007;
while (in[tmp] && in[tmp] != x)
tmp = (tmp + 1) % 1000007;
return tmp;
}
int main() {
scanf("%d %d", &n, &k);//读入
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);//读入
for (int i = 1; i <= n; i++) {
int ha = get_hash(a[i]);//得出这个数的hash值
q.push(a[i]);//加入的队列
if (!in[ha]) {//队列中没有
kind++;//种数增加
in[ha] = a[i];//记录
while (kind > k + 1)//超过了要求
{
int now = q.front();//提出对首的数
q.pop();
num[get_hash(now)]--;
if (!num[get_hash(now)]) {//这一个数在序列中没有了
in[get_hash(now)] = 0;
kind--;
}
}
}
num[ha]++;//记录
ans = max(ans, num[ha]);//是否有超过最大值
}
printf("%d", ans);//输出
}