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