JZOJ100046.收集卡片 (Standard IO)
\[Description
\]
Star 计划订购一本将要发行的周刊杂志,但他可不是为了读书,而是—— 集卡。 已知杂志将要发行 N 周(也就是 N 期),每期都会附赠一张卡片。Star 通 过种种途径,了解到 N 期杂志附赠的卡片种类。Star 只想订购连续的若干期, 并在这些期内收集所有可能出现的种类的卡片。现在他想知道,他最少需要订 购多少期。
\[Input/Output
\]
第一行一个整数 N;
第二行一个长度为 N 的字符串,由大写或小写字母组成,第 i 个字符表示 第 i 期附赠的卡片种类,每种字符(区分大小写)表示一种卡片。
输出一行一个整数,表示 Star 最少订购的期数。
\[Sample
\]
8
acbbbcca
3
\[Data\ Constraint
\]
对于 \(100\)% 的数据,\(N ≤ 500000\)。
一开始写了二分,时间复杂度 \(O(N \log N)\),常数是 \(52\) —— \(80\) 分。
随后一下想到队列(当然随后是指考后)
// T1
Uses math;
var
bucket:array[-1..530] of longint;
i,n,num,ans,head,tail,kind:longint;
s:ansistring;
begin
readln(n); readln(s); num:=0; head:=1; ans:=n;
for i:=1 to n do
begin
if bucket[ord(s[i])]=0 then inc(kind);
bucket[ord(s[i])]:=1;
end;
filldword(bucket,sizeof(bucket) div 4,0);
for tail:=1 to n do
begin
if bucket[ord(s[tail])]=0 then inc(num);
inc(bucket[ord(s[tail])]);
while num>=kind do
begin
if num=kind then ans:=min(ans,tail-head+1);
dec(bucket[ord(s[head])]); if bucket[ord(s[head])]=0 then dec(num);
inc(head);
end;
end;
writeln(ans);
end.
完结撒花!✿✿ヽ(゚▽゚)ノ✿