1. 程式人生 > >3464. 【NOIP2013模擬聯考6】秀姿勢(sugata) (Standard IO)

3464. 【NOIP2013模擬聯考6】秀姿勢(sugata) (Standard IO)

序列 begin 名單 RoCE 次數 scrip 入學 desc 定義

Description

“藍貓淘氣三千問,看藍貓,我有姿勢我自豪!”話說能考上HYSBZ的孩紙們肯定都是很有姿勢的孩紙們,但是大家普遍偏科,都只有一門科目考得好。已知HYSBZ的入學考試科目數量小於等於10^9,而有n個學生參加了入學考試。現在HYSBZ要刷人了,招生辦每一次刷人會把一個科目考得好的人全部刷掉,但是最多不能刷超過K次。(刷就是不錄取)而HYSBZ的校長看錄取名單時,最喜歡看的就是連續都是同一個科目考得好的人。他定義完美學生序列為連續且考得好的科目都為同一門的學生序列。現在招生辦主任想讓你幫他設計一種錄取方案,使得最長的完美學生連續子序列盡量長。

Input

共N+1行,第一行2個正整數n,K,n表示入學考試人數,K表示刷人次數上限。
接下來N行,每行僅一個正整數Ai,為i號學生所考得好的科目。

Output

僅1個正整數,為最長的最長完美學生連續子序列。
Solutions

用隊列維護一個區間,使得這個區間的擅長科目數量不超過 K+1, 那麽統計出來的每個合法區間的眾數的數量的最大值便為答案。具體操作 如下:

(1).首先添加第一個元素入隊列,此時 Head=Tail=1

(2).接下來不斷添加元素入隊,當隊列內元素種類不大於 K+1 時統計答案。

(3).當隊列裏的元素種類大於 K+1 時,不斷將隊列頭部的元素出隊,直到 隊列內元素種類小於等於 K+1,這時要記得也要統計答案。 這便是這道題的算法。

時間復雜度 O(n)

代碼

 1 const
 2   maxn=1000000;
 3 var
 4   n,k,ans:longint;
 5   f,a:array[0..100001]of longint;
 6   ha:array[0..1000000,1..2]of longint;
 7 function max(o,p:longint):longint;
 8 begin
 9   if o>p then exit(o);
10   exit(p);
11 end;
12 
13 function hash(x:longint):longint;
14 var
15 i:longint; 16 begin 17 i:=x mod maxn; 18 while (ha[i,1]<>0) and (ha[i,1]<>x) do 19 i:=(i+1) mod maxn; 20 exit(i); 21 end; 22 23 procedure init; 24 var 25 i:longint; 26 begin 27 read(n,k); 28 for i:=1 to n do 29 read(a[i]); 30 end; 31 32 procedure main; 33 var 34 i,j,head,tail,num:longint; 35 begin 36 head:=1; tail:=0; 37 ans:=1; num:=0; 38 for i:=1 to n do 39 begin 40 inc(tail); 41 j:=hash(a[i]); 42 if ha[j,1]=0 then 43 begin 44 inc(num); 45 ha[j,1]:=a[i]; 46 ha[j,2]:=1 47 end else 48 begin 49 inc(ha[j,2]); 50 ans:=max(ans,ha[j,2]); 51 end; 52 f[tail]:=a[i]; 53 while num>k+1 do 54 begin 55 j:=hash(f[head]); 56 dec(ha[j,2]); 57 if ha[j,2]=0 then 58 begin 59 ha[j,1]:=0; 60 dec(num); 61 end; 62 inc(head); 63 end; 64 end; 65 end; 66 67 begin 68 init; 69 main; 70 writeln(ans); 71 end.

3464. 【NOIP2013模擬聯考6】秀姿勢(sugata) (Standard IO)