秀姿势(sugata)

姿(sugata)秀姿势(sugata)

题目链接:jzoj 3464jzoj\ 3464

题目

“蓝猫淘气三千问,看蓝猫,我有姿势我自豪!”话说能考上HYSBZHYSBZ的孩纸们肯定都是很有姿势的孩纸们,但是大家普遍偏科,都只有一门科目考得好。已知HYSBZHYSBZ的入学考试科目数量小于等于10910^9,而有nn个学生参加了入学考试。现在HYSBZHYSBZ要刷人了,招生办每一次刷人会把一个科目考得好的人全部刷掉,但是最多不能刷超过KK次。(刷就是不录取)而HYSBZHYSBZ的校长看录取名单时,最喜欢看的就是连续都是同一个科目考得好的人。他定义完美学生序列为连续且考得好的科目都为同一门的学生序列。现在招生办主任想让你帮他设计一种录取方案,使得最长的完美学生连续子序列尽量长。

输入

N+1N+1行,第一行22个正整数nnKKnn表示入学考试人数,KK表示刷人次数上限。

接下来NN行,每行仅一个正整数AiA_i,为ii号学生所考得好的科目。

输出

11个正整数,为最长的最长完美学生连续子序列。

样例输入

9 1

2

7

3

7

7

3

7

5

7

样例输出

4

样例解释

总共有99个学生,最多只能刷一次学生。

若不刷,最长完美学生连续子序列长度为22

若刷掉考第33门考得好的学生,则学生序列变成2 7 7 7 7 5 72\ 7\ 7\ 7\ 7\ 5\ 7,最长完美学生连续子序列长度为44.

数据范围

对于10%10\%的数据:n ⁣<= ⁣10n\!<=\!10
对于30%30\%的数据:n ⁣<= ⁣1000n\!<=\!1000
对于100%100\%的数据:1 ⁣<= ⁣n ⁣<= ⁣1000001\!<=\!n\!<=\!100000

思路

doge{\color{white}这学校招学生的方式怎么这样,真就看谁脸白排的位置好啊(doge)}

这道题是一道模拟题吧。

我们就不停的维护一个连续的且数的种类不超过K+1K + 1的序列,那么我们把它这个序列中数量少的KK个踢掉,就只剩一个数量最长的完美学生连续子序列了。
那我们就不停的维护,然后中途不停的找最长完美学生子序列,找到最大的那个,就是答案了。

代码

#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);//输出
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章