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.
posted @ 2018-12-15 14:34  _ARFA  阅读(133)  评论(0编辑  收藏  举报